2016-04-21 4 views
0

Ich habe ein seltsames Problem. Ich habe ein Beispiel gegeben und erklärt, was das Problem ist. Ich habe 4 Klassen, eine, die einen Zeiger auf eine Klasse bekommt, die 2 anderen innewohnt. Hier ist, wie es aussieht: Die Inhärenzien Klassen:Klasse Inhärenz virtuelle Zeichenfolge nicht das richtige zurück

class classA{ 
public: 
    classA(){} 
    virtual std::string getType(){return "classA";} 
    classA& operator=(const classA& classa) {return *this;} 

}; 

class classB: public classA { 
    int b; 
public: 
    classB(int n){b=n;} 
    virtual std::string getType() { return "classB"; } 
    void setB(const int b){this->b=b;} 
    int getB() const{return this->b;} 
}; 

class classC: public classA { 
    int c; 
public: 
    classC(int n){c=n;} 
    virtual std::string getType() { return "classC"; } 
    void setC(const int c){this->c=c;} 
    int getC() const{return this->c;} 
}; 

Die einzige wichtige Sache ist die getType() Funktion.

Hier ist jetzt die Klasse, die einen Zeiger auf classA

class superClass{ 
    classA* _classA; 
    int nb; 
public: 
    superClass(){nb=0;} 
    void addElement(classA& e){ 
    classA *newTab=new classA[++nb]; // create tab as the same size than the other +1 
    for(int i=0;i<nb-1;i++) 
     newTab[i]=_classA[i]; // add element from the old class to the new one 
    newTab[nb-1]=e; // add the element 
    //delete[] _classA; 
    _classA=newTab; // now copy it to the class 
    //delete[] newTab; 
    } 
    classA* getClass() {return _classA;} 
    int getNb() const{return this->nb;} 

    void displayElements(){ 
    for(int i=0;i<getNb();i++) 
     std::cout << _classA[i].getType() << std::endl; 

    } 
}; 

addElemment() ist eine Funktion, die ein classA Element mit einem Raum malloc bekommen mehr, die es mit den ancien Elementen gefüllt wird dann fügt es die neue Element und hier geht es. Es funktioniert aber das Problem ist hier. Ich verwende kein classA-Element, nur seine untergeordneten Elemente. Ich möchte classB Elemente und classC Elemente die superClass hinzufügen und den Klassen-Typ mit getType() erhalten; Hier ist die Hauptdatei

int main(int argc, char const *argv[]) 
{ 
    classB *classb = new classB(9); 
    classC *classc = new classC(10); 

    superClass super; 
    super.addElement(*classb); 
    super.displayElements(); 
    // Display "classA" instead of "classB" 

    super.addElement(*classc); 
    super.displayElements(); 
    // Display "classA" and "classA" instead "classB" and "classC" 

    //std::cout << classb->getType() << std::endl; // return ClassA 
    //std::cout << classc->getType() << std::endl; // return ClassA 

    return 0; 
} 

Ich will nur mein Programm die richtige Klasse anzeigen, das Kind eine Klasse. Das Problem kommt mit addElement(), denke ich. Ich habe versucht, virtuelle std::string getType()=0; zu verwenden, aber es funktioniert immer noch nicht, es ändert nichts.

Ich habe auch versucht Vorlage aber ändert nichts mit und nicht

Meine Frage funktioniert: ich mein Programm will das Kind Klasse statt classA jedes Mal angezeigt wird.

+2

Hinweis: __object slicing__ – emlai

+0

ich nicht darüber wusste, ich danke es bei der Suche – Hearner

+0

Ich verstehe, was es ist, aber in meinem Beispiel kann ich nicht die Adresse übergeben die superClass, weil die Funktion bereits eine superClass :: superClass() ohne Parameter ist – Hearner

Antwort

1

Sie sollten das Deklarationselement _classA in superClass wie folgt ändern: classA ** _classA ;. So würde es so aussehen:

class superClass 
{ 
    classA** _classA; 
    int nb; 
public: 
    superClass():_classA(0) // you also should initialize this to avoid crash while first delete[] of this _classA 
    { 
     nb = 0; 
    } 

    ~superClass() // also you should add destructor to free memory 
    { 
     for (int i = 0; i < nb; i++) 
     { 
      delete _classA[i]; 
      _classA[i] = nullptr; 
     } 
     delete[] _classA; 
     _classA[i] = nullptr; 
    } 

    void addElement(classA& e) 
    { 
     int oldSize = nb; 
     nb++; // increment the size separately for clarity 
     classA **newTab = new classA*[nb]; // create tab as the same size than the other +1 
     for (int i = 0; i < oldSize; i++) 
     newTab[i] = _classA[i]; // add element from the old class to the new one 
     classA* newElement = new classA(e); // use the copy-constructor 
     newTab[oldSize] = newElement; // add the element 
     delete[] _classA; // now you can free it 
     _classA = newTab; // now copy it to the class 
    } 
    classA** getClass() 
    { 
     return _classA; 
    } 
    int getNb() const 
    { 
     return this->nb; 
    } 

    void displayElements() 
    { 
     for (int i = 0; i < getNb(); i++) 
     std::cout << _classA[i]->getType() << std::endl; 

    } 
}; 
+0

Danke, mit ** macht den Trick. Kannst du mir erklären, warum das funktioniert?Vielen Dank, aber ich würde gerne wissen warum ^^ – Hearner

+0

'~ superClass() { löschen [] _classA; } stürzt am Ende des Programms ab (Signal SIGABRT) – Hearner

+0

Keine Möglichkeit, wenn Sie das _classA-Member korrekt initialisiert haben, dh schauen Sie sich Konstruktor noch einmal an, dass es "superClass(): _ classA (0)" sein sollte, um einen solchen Absturz zu vermeiden . –

0

newTab ist ein Array von classA. Daher kann es keine classB Objekte, nur classA Objekte enthalten.

newTab[nb-1]=e; 

Wenn hier auf ein eclassB Objekt bezieht, Scheiben diese Zuordnung den classB Teil von ihm weg, so wird es ein classA Objekt und kann in dem Array passen. Dies ist bekannt als object slicing.

+0

Danke, dass Sie sich die Zeit nehmen zu antworten. Ich habe etwas darüber gelesen, aber wie kann ich es vermeiden? Was soll ich tun, um in meinem Beispiel das Richtige zu zeigen? – Hearner

Verwandte Themen