Vererbung ändern



  • Hallo.

    Ich habe folgende Architektur:

    class CEquation{
    protected:
    
    public:
        CEquation(){}
    
        virtual EquationTypeENUM Type(){return EquationTypeENUM::Poission;}
    
        void ChangeType(EquationTypeENUM Type){
            switch(Type){
                case EquationTypeENUM::Poisson:
                    /*Change to CPoisson*/
                    break;
                default:
                    /*Change to CLaplace*/
                    break;
            }
        }
    }
    
    class CPoisson : public CEquation{
    protected:
    
    public:
        CPoisson() : CEquation(){
    
        }
    
        EquationTypeENUM Type() override {return EquationTypeENUM::Poission;}
    }
    
    class CLaplace : public CEquation{
    protected:
    
    public:
        CLaplace() : CEquation(){
    
        }
    
        EquationTypeENUM Type() override {return EquationTypeENUM::Laplace;}
    }
    

    Mein Hauptprogramm sieht in etwa so aus:

    static CEquation** CEquationStack = NULL;
    static int nEquation = 0;
    
    int main(){
        CEquation* EQ = AddEquation(); /*Function adds CEquation to global CEquationStack*/
        EQ->ChangeType(EquationTypeENUM::Laplace);
    
        /*What do I have to define in the ChangeType-Function? Is it possible,
          that the address of EQ does not change while changing the class? I'm
          using references to classes in my programm.*/
    }
    
    CEquation* AddEquation(){
        nEquation++;
    
        if(nEquation < 2)
        {
            if(CEquationStack != NULL){free(CEquationStack);}
            CEquationStack = (CEquation**)malloc(sizeof(CEquation*));
        }else{
            CEquationStack = (CEquation**)realloc(CEquationStack, nEquation * sizeof(CEquation*));
        }
    
        if(CEquationStack==NULL){return NULL;}
        CEquationStack[nEquation - 1] = new CEquation();
    
        return CEquationStack[nEquation - 1];
    }
    

    Wie muss die Funktion ChangeType aussehen? Ist es möglich, dass sich dabei die Adresse der Klasse nicht ändere? Ich nutze die Referenz auf die Klasse CEquation sehr häufig. Oder muss die Klasse beim Ableiten stets neu instanziert werden?

    Grüße,
    CJens


  • Mod

    Der Typ eines Objekts kann nicht geändert werden. Was du machen kannst ist, es durch ein neues Objekt vom gewünschten Typ zu ersetzen.

    Ich würde an deiner Stelle aber zwei Sachen dringend überdenken:
    a) Extrem dringend: Wie du mit Speicher hantierst. C-Speicherverwaltung mit C++-Klassen ist Gift. In C++ solltest du eigentlich gar nicht von Hand mit Speicher hantieren, sondern eine der vielen fertigen Container benutzen. Oder wenn es unbedingt (zu Lehrzwecken?) sein muss, dass du es von Hand machen musst, dann nutz wenigstens die C++-Methoden. Wobei du bei deiner Speicherverwaltung momentan so ziemlich alles falsch machst, was falsch machbar ist. Wenn es also zu Lehrzwecken sein soll, dann solltest du entweder lernen, wie du es ganz bleiben lässt (wie gesagt: Container), oder ganz dringend die Grundlagen dazu angucken.
    b) Deine Klassenhierarchie. Dein Problem kommt ja gerade daher, dass du nicht so recht das Klassen und Objektkonzept von C++ verstanden zu haben scheinst. Ich weiß anhand des Beispiels nicht, welche Art von Architektur besser wäre, da ich in dem Beispiel nicht verstehe, wieso überhaupt erst ein Objekt der falschen Klasse erzeugt wird. Kann's sein, dass du einfach nur virtuelle Funktionen suchst und nicht kennst?



  • Hallo.

    Ich programmiere hier einen Kernel für numerische berechnungen - ich habe eine strenge Architektur und möchte diese über Zeiger verwirklichen.

    Klassen dienen mir hier als funktionale Objekte - eine Klasse CEquation ist eine Gleichung - aber es gibt unterschiedliche Gleichungen zur Auswahl.

    Es handelt sich hierbe um eine DLL - ich greife über ein C# Programm darauf zu - deshalb ist es sehr wichtig, dass jedes Objekt über eine Adresse aufrufbar ist und eine Wurzeln der Struktur ist z.B. CEquationStack.

    In C# leite ich dann über ein TreeNode-Element eine Wraper Klasse ab und greife darüber auf die Objekte in der DLL zu. Der User hat dann ein PropertyGrid für das Objekt CEquation und kann dort über ein DropDown Menü "Typ" vom "Poisson" zu "Laplace" ändert. Dann sollen gemeinsame Referenzen erhalten bleiben, und neue idealerweise über den spezifischen Konstruktor gesetzt werden. Aber wenn das nicht geht, kann ich natürlich die Adresse der Instanz an die "ChangeType" Function übergeben und diese dann durch die Adresse einer neuen Istanz + Spezifischen CopyKonstruktor - ersetzen.


Log in to reply