Instanz aus mehreren abgeleiteten Klassen erzeugen



  • Hallo zusammen,

    ich habe mal eine Frage zur optimalen Steuerung bzw. gut organisiertem Code um eine Instanz aus unterschiedlichen abgeleiteten Klassen zu erzeugen. Hier erstmal etwas Beispiel Code:

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #include <iostream>
    #pragma hdrstop
    
    #include "Main.h"
    #include "BasisClass.h"
    #include "SubClass1.h"
    #include "SubClass2.h"
    //---------------------------------------------------------------------------
    #pragma package(smart_init)
    #pragma resource "*.dfm"
    using namespace std;
    
    CSub1 *TF1 = 0;       // Zeiger auf Objekt der SubClass1
    CSub2 *TF2 = 0;       // Zeiger auf Objekt der SubClass2
    // etc. ...
    
    Sub1Parameters SUB1;  // Definition von Strukturvariablen
    Sub2Parameters SUB2;  // zur Parameterübergabe von und zum Objekt
    // etc. ...
    
    int iValue;           // Wählt die abgeleitete Klasse aus
    
    TForm1 *Form1;
    //---------------------------------------------------------------------------
    
    __fastcall TForm1::TForm1(TComponent* Owner)
    	: TForm(Owner)
    {
     iValue = 0;    // iValue wird an anderer Stelle im Programm gesetzt
     //iValue = 1;  // und bestimmt die abgeleitete Klasse von der eine
    	       // Instanz erzeugt werden soll.
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
     if ( TF1 || TF2 ) deleteTF();
     switch ( iValue )
       {
    	case 0: TF1 = new CSub1();
    			TF1->getSub1Setup( &SUB1 );
    			break;
    	case 1: TF2 = new CSub2();
    			TF2->getSub2Setup( &SUB2 );
    			break;
    	// etc. ...
       }
     ListBox1->Items->Add("A = " + IntToStr(SUB1.iA) +
    					  ", B = " + IntToStr(SUB1.iB) +
    					  ", I1 = " + IntToStr(SUB1.iI1) +
    					  ", I2 = " + IntToStr(SUB1.iI2));
     ListBox1->Items->Add("A = " + IntToStr(SUB2.iA) +
    					  ", B = " + IntToStr(SUB2.iB) +
    					  ", J1 = " + IntToStr(SUB2.iJ1) +
    					  ", J2 = " + IntToStr(SUB2.iJ2));
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::deleteTF()
    {
     if ( TF1 )
       {
    	delete TF1;
    	TF1 = 0;
       }
     if ( TF2 )
       {
    	delete TF2;
    	TF2 = 0;
       }
     // etc. ...  
    }
    //---------------------------------------------------------------------------
    

    Ich suche nach einer Möglichkeit über eine Schleife das Löschen des Objektes und evtl. über Felder das Aufrufen der Methoden in mehreren Funktionen einfacher zu handhaben, also nicht für jedes unterschiedliche Objekt eine eigene Behandlungsfunktion/Abfrage zu haben.

    In meinem Programm gibt es immer nur eine Instanz von einer abgeleiteten Klasse die über das Programm ausgewählt wird, eine Basisklasse aber mehrere abgeleitete Klassen (und es kommen auch noch neue Ableitungen hinzu). Im Moment hänge ich an diesem Ablauf fest und es fällt mir keine bessere Lösung ein. Bei 2 Ableitungen wäre das kein Problem, aber wenn es mehrere sind ist das so relativ aufwendig. Aber da gibt es doch bestimmt eine einfachere Lösung dafür, oder ?!

    Danke für jeden Tip

    WoWe



  • Hallo, seh ich das richtig, das CSub1 und CSub2 von der gleichen basisklasse erben?

    class Base{
    
    virtual Funk()=0;
    virtual ~Base(){..};
    
    };
    
    class CSub1 : public Base{
    
    virtual Funk(){...tu was mit CSub1 daten... }
    virtual ~CSub1(){..};
    };
    
    class CSub2 : public Base{
    
    virtual Funk(){...tu was mit CSub2 daten... }
    virtual ~CSub2(){..};
    };
    

    jetzt kannst du alle Instaanzen der CSub1 und CSub2 Klasse in eine array oder Liste aus Base pointer anlegen..

    Base *p[100];
    
    p[0]= new Sub1();
    p[1]= new Sub2();
    ....
    

    wennn du nun p[0] löscht, wird automatisch der destruktor von sub1 aufgerufen egro p[1] von Sub2

    wenn du

    p[0]->Funk();
    

    machst wird die methode der sub1 aufgerufen ... p[1] dann von Sub2

    einfach polymorphy vewenden...



  • Hallo BorisDieKlinge,

    vielen Dank für deine Hilfe. Das werde ich mal studieren. Wahrscheinlich komme ich nochmal mit der ein oder anderen Frage.

    WoWe



  • Hallo,

    jetzt habe ich doch nochmal 2 Fragen dazu:

    Basis.h

    //---------------------------------------------------------------------------
    
    #ifndef BasisClassH
    #define BasisClassH
    
    struct Sub1Parameters
    {
      int iA;
      int iB;
      int iI1;
      int iI2;
      // etc.
    };
    
    struct Sub2Parameters
    {
      int iA;
      int iB;
      int iJ1;
      int iJ2;
      // etc.
    };
    
    class CBasis
    {
     private:
    	int m_A, m_B;
    
     public:
    	__fastcall CBasis();
    	virtual __fastcall ~CBasis();
    	__fastcall getIntA() const {return m_A;}
    	__fastcall getIntB() const {return m_B;}
    	void __fastcall setIntA( int A ) {m_A = A;}
    	void __fastcall setIntB( int B ) {m_B = B;}
    	virtual void __fastcall getSub1Setup( Sub1Parameters * ) const;
    	virtual void __fastcall getSub2Setup( Sub2Parameters * ) const;
    	// Methoden ...
    };
    //---------------------------------------------------------------------------
    #endif
    

    Basis.cpp

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #include <iostream>
    #pragma hdrstop
    
    #include "BasisClass.h"
    #include "Main.h"
    
    //---------------------------------------------------------------------------
    
    #pragma package(smart_init)
    using namespace std;
    
    __fastcall CBasis::CBasis()
    {
     m_A = 1;
     m_B = 2;
     Form1->ListBox1->Items->Add("Basis Konstruktor");
    }
    //---------------------------------------------------------------------------
    
    __fastcall CBasis::~CBasis()
    {
     Form1->ListBox1->Items->Add("Basis Destruktor");
    }
    //---------------------------------------------------------------------------
    
    void __fastcall CBasis::getSub1Setup( Sub1Parameters *Setup ) const
    {
    }
    //---------------------------------------------------------------------------
    
    void __fastcall CBasis::getSub2Setup( Sub2Parameters *Setup ) const
    {
    }
    //---------------------------------------------------------------------------
    

    SubClass1.h

    //---------------------------------------------------------------------------
    
    #ifndef SubClass1H
    #define SubClass1H
    #include "BasisClass.h"
    
    class CSub1 : public CBasis
    {
     private:
    	int m_I1, m_I2;
    
     public:
    	__fastcall CSub1();
    	__fastcall ~CSub1();
    	void __fastcall getSub1Setup( Sub1Parameters * ) const;
    	void __fastcall setSub1Setup( const Sub1Parameters & );
    };
    //---------------------------------------------------------------------------
    #endif
    

    SubClass1.cpp

    //---------------------------------------------------------------------------
    
    #include <vcl.h>
    #include <iostream>
    #pragma hdrstop
    
    #include "SubClass1.h"
    #include "Main.h"
    
    //---------------------------------------------------------------------------
    
    #pragma package(smart_init)
    using namespace std;
    
    __fastcall CSub1::CSub1()
    {
     m_I1 = 10;
     m_I2 = 11;
     Form1->ListBox1->Items->Add("Sub1 Konstruktor");
    }
    //---------------------------------------------------------------------------
    
    __fastcall CSub1::~CSub1()
    {
     Form1->ListBox1->Items->Add("Sub1 Destruktor");
    }
    //---------------------------------------------------------------------------
    
    void __fastcall CSub1::getSub1Setup( Sub1Parameters *Setup ) const
    {
     Setup->iA = getIntA();
     Setup->iB = getIntB();
     Setup->iI1 = m_I1;
     Setup->iI2 = m_I2;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall CSub1::setSub1Setup( const Sub1Parameters & New )
    {
     m_I1 = New.iI1;
     m_I2 = New.iI2;
     setIntA( New.iA );
     setIntB( New.iB );
    }
    //---------------------------------------------------------------------------
    

    Also zuerst einmal, das funktioniert so, aber ich bin mir nicht sicher ob meine Schreibweise so korrekt ist, deshalb nochmal 2 Fragen:

    1. Muss ich so wie oben jede Spezialfunktion einer abgeleiteten Klasse auch als "virtual Dummy" in der Basisklasse aufnehmen ?

    2. Muss das Schlüsselwort "virtual" auch in den abgeleiteten Klassen vor den Funktionen stehen bzw. werden die Funktionen in den abgeleiteten Klassen nicht automatisch zu virtual? Geht auch ohne !

    Danke und Gruß

    WoWe


Anmelden zum Antworten