Vererbte Klasse -> Zeiger Problem



  • Guten Tag,
    ich habe ein Problem bei der Erstellung eines Objektes auf eine Klasse.
    Ich habe 2 Klassen, wobei eine davon vererbt ist:

    class k1{
    	public:
    	int a;
    
    	int aa(){
    		cout << "aa";
    	}
    };
    class k2 : public k1{
    	public:
    	int b;
    
    	int bb(){
    		cout << "bb";
    	}
    };
    

    Nun möchte ich das Objekt so erstellen, dass der Pointer zuerst auf Klasse1 zeigt und danach auf Klasse2, so dass ich Zugriff auf die Methoden & Attribute der Klasse1 habe.
    Ich habe es so versucht:

    k1* asdf;
    k1 = new k2;
    

    Jedoch habe ich weiterhin nur Zugriff auf die Attribute & Methoden der 1sten Klasse. Der Konstruktor von Klasse2 wird aufgerufen.
    Was mache ich falsch ?
    Bin über jede Hilfe/Ansatz dankbar.

    MfG
    Inco



  • Wenn dein Objekt vom Typ k1 ist, hast du natürlich auch nur Zugriff auf die Methoden von k1. Wenn du Zugriff auf die Methoden von k2 haben willst musst du nach k2 casten.



  • IncogNito schrieb:

    Jedoch habe ich weiterhin nur Zugriff auf die Attribute & Methoden der 1sten Klasse. Der Konstruktor von Klasse2 wird aufgerufen.
    Was mache ich falsch ?

    Grundsätzlich kannst du (in nahezu jeder mir bekannten Sprache) auch nur auf das Zugreifen was du angibst. Wenn du einen Zeiger auf einen Typ k1 hast, kannst du auch nur dessen Schnittstelle verwenden.

    Ganz davon abgesehen:
    1. Man sollte öffentliche Membervariablen vermeiden
    2. NIEMALS using namespace im Header verwenden!
    3. Basisklassen sollten möglichst einen virtuellen Destruktor besitzen (Sonst kann es sein, das ein Objekt das über einen Basisklassenzeiger gelöscht wird, nicht vollständig aufgeräumt wird).

    Was aber möglich ist, ist mit virtuellen Funktionen die "richtige" Implementierung zu verwenden.

    class k1{
        public:
          virtual void foo() {
              std::cout << "aa";
          }
          virtual ~k1() {}
    };
    class k2 : public k1{
        public:
          void foo(){
            std::cout << "bb";
          }
    }; 
    
    int main()
    {
        k1* a = new k2;
        a->foo();
        delete a;
    }
    


  • EDIT: mal wieder zu lange gebraucht. 😉 Ich lass es einfach mal stehen.
    ----------------------------

    ... oder (was besser als Casten und/oder vermutlich von Dir gemeint ist): Polymorphie verwenden.

    IncogNito schrieb:

    ...
    Nun möchte ich das Objekt so erstellen, dass der Pointer zuerst auf Klasse1 zeigt und danach auf Klasse2, so dass ich Zugriff auf die Methoden & Attribute der Klasse1 habe....

    Der klassische (und vom Sprachstandard unterstützte) Weg ist, in k1 bereits festzulegen, welche Schnittstelle seine "Erben" unterstützen werden:

    struct k1{
       int a;
       int aa(){ cout << "aa"; }
       virtual int bb() = 0; // sagt: "Wer von mir erbt, soll das hier implementieren" und
       // "ohne das zu implementieren, kann man mich nicht erzeugen"
    };
    
    struct k2 : k1{
       int b;
       int bb(){ cout << "bb"; }
    };
    

    Das ist auch konsistent mit dem, was man mit "Vererbung" eigentlich ausdrücken möchte: Eine "Ist-ein"-Relation - "ein k2-Objekt IST EIN k1-Objekt".

    Angewendet würde es dann:

    k1* asdf = new k2; // natürlich wird hier AUCH der k2-Konstruktor aufgerufen
          // aber eben AUCH der k1-Konstruktor
    
       asdf->aa(); // k1::aa()
       asdf->bb(); // k2::bb()
    
       cout << asdf->b; // -> Compile-Fehler; asdf sagt nur zu, auf ein k1 zu zeigen.
    

    Gruß,

    Simon2.



  • Vielen Dank an alle für die hilfreichen Tips + Beispiele. 🙂
    Mein Problem war das -> virtual, weil ich nicht gewusst habe das das damit zusammenhängt. Danke nochmal! 🙂

    Gruß Inco


Anmelden zum Antworten