C++ Vererbung austricksen?



  • Hallo zusammen,

    ich habe eine Klasse A, welche von einem Generator erzeugt wird. Diese Sieht im wesentlichen so aus:

    class A: public B {
    public:
            bool X(); // defined but not implemented in A.cpp
    	void Y(){Z();}
    
    	void Z(){X();}
    };
    

    B wurde von mir erstellt:

    class B : public SuperKlasse {
    public:
    };
    

    Wie man sieht, fehlt eine Implementierung für A::X(). Nun habe ich aber durch den Generator nicht nur ein A bekommen, sondern viele A's. Diesen fehlt allen eine Implementierung von X(). Die ist aber überall die gleiche. Kann man nun die Vererbung irgendwie austricksen, so dass ich X() schon in B definieren kann? Vermutlich nicht, da X() schon in A definiert ist, oder?

    Vielen Dank.



  • Ich weiß, Vererbung austricksen ist ein wenig unsauber formuliert. Ich vermute, dadurch, dass X() in A definiert ist, ist bereits so eine "Art vtable Eintrag" für den Linker vorhanden und daher auch der Fehler. Müsste man halt irgendwie löschen können ... mh.



  • Deine Beschreibung ist ziemlich wirr.
    Vielleicht meinst du eine rein virtuelle Methode:

    virtual X() = 0;
    

    , denn die kannst du dann in A ueberschreiben.



  • Dies müßte gehen:

    class B
    {
      virtual bool X()
      {
        return true; // or whatever
      }
    }
    

    Also einfach X als virtuelle Funktion in B definieren (und implementieren).
    Die Neudeklaration in der A-Klasse (bzw. den verschiedenen A-Klassen) dürfte dann dem Compiler nicht stören.

    @Marthog: sven_ meint es umgekehrt 😉

    PS: Was ist denn das für ein Generator, der fehlerhaften Code (oder doch gewollt?!) erzeugt?



  • Hallo zusammen,

    fandet ihr meine Beschreibung wirr? Dachte eigentlich ist straight forward. Der Code stammt aus einem Testframework Generator, welcher auf Google Test aufbaut.

    Den Ansatz mit einem: virtuel bool X(){return true; } in B habe ich auch probiert. Der Compiler (gcc477 mit C++11) nimmt es, aber der Linker sagt:

    main.cc:19: undefined reference to `vtable for A'
    collect2: error: ld returned 1 exit status
    

    Meine main ist dabei einfach nur:

    int
    main(int argc, char** argv) {
        A a; //<<-- line 19
        return 0;
    }
    

    Klar kann ich auch in A jedes mal die Dekleration von X() auskommentieren, wenn man aber zig As hat, ist das nicht so ne coole Lösung.



  • Wenn du

    B.h

    virtual bool X(){return true; }
    

    machst und A sich nicht anders verhalten soll als B, musst du natürlich die Deklaration von X() aus deiner Klasse A entfernen.
    Ansonsten musst du für deine Klasse A, die Methode X() überschreiben ... und da gehört halt zu einer Deklaration auch eine Definition.

    class A: public B {
    public:
        bool X() 
        { 
          // Method definition
          // do sth. different like returning false
          return false; 
        }  
        void Y(){Z();}
    
        void Z(){X();}
    };
    


  • ja, dass hab ich mir schon gedacht. dachte es gibt so bissl was "magisches" wie man ihn dazu bringen kann die deklaration zu ignorieren. wollte auch nur sicher gehen, dass meine gedanken gänge stimmen. vielen dank. 😉



  • Es gibt auch die Möglichkeit eine rein virtuelle Methode in der Basisklasse zu definieren, und dort auch eine Implementierung mitzugeben. Auf die könntest du dann zugreifen.



  • Es gibt da zwei Moeglichkeiten. Du kannst vor die Deklaration ein // haengen oder du umschliesst die Deklaration mit /* und */. Dann wird alles schoen ignoriert!


Anmelden zum Antworten