Problem mit Polymorphie



  • Hallo,

    ich habe ein kleines Problem mit der Polymorphie in C++. In meinem Beispiel habe ich eine Elternklasse B mit zwei Funktionen selben Namens, aber mit unterschiedlicher Signatur.
    Sobald ich in der abgeleiteten Klasse nur eine der Beiden überschreiben will, gibt es einen Compiler-Fehler.

    class B{
            public:
                    virtual void s() {}
                    virtual void s(int){};
    };
    
    class C : public B {
            public:
                    virtual void s(int){}; // without this line it compiles!
    };
    
    int main() {
            C c;
            c.s();
    };
    

    main.cc: In function 'int main()':
    main.cc:16: error: no matching function for call to 'C::s()'
    main.cc:11: note: candidates are: virtual void C::s(int)

    Ich bin mir nicht sicher, ob dies nun ein generelles C++ Problem ist, und ob es dafür eine Lösung gibt, oder ob es vom Compiler abhängt (gcc version 4.0.1 (Apple Inc. build 5465))
    Über Hilfe mit meinem Problem würde ich mich sehr freuen.

    Vielen Dank!

    Stefan



  • Hallo,

    Ich bin mir nicht sicher, ob dies nun ein generelles C++ Problem ist,

    Ja, ist es.

    und ob es dafür eine Lösung gibt

    Die s-Funktionen nicht virtual machen, dafür aber in s eine virtuelle Funktion mit fester Signatur aufrufen.



  • Sobald in einer abgeleiteten Klasse eine Memberfunktion neu deklariert wird – ob virtuell oder nicht, spielt keine Rolle – verdeckt sie die anderen Funktionen gleichen Namens, die in einer Basisklasse deklariert wurden. Um dieses Problem zu umgehen, kannst du das Schlüsselwort using einsetzen:

    class C : public B
    {
        public:
            using B::s;
            virtual void s(int);
    };
    

    Jockelx schrieb:

    Die s-Funktionen nicht virtual machen, dafür aber in s eine virtuelle Funktion mit fester Signatur aufrufen.

    Mit virtual hat das in erster Linie wie erwähnt nichts zu tun. Das Problem hat StefanUI weiterhin, falls er eine Funktion erst in einer abgeleiteten Klasse überladen möchte. Deshalb using .



  • Versuch mal:

    class B{
            public:
                    virtual void s() {}
                    virtual void s(int){}
    };
    
    class C : public B {
            public:
                    using B::s;
                    virtual void s(int){}
    };
    
    int main() {
            C c;
            c.s();
    }
    


  • Nexus schrieb:

    Jockelx schrieb:

    Die s-Funktionen nicht virtual machen, dafür aber in s eine virtuelle Funktion mit fester Signatur aufrufen.

    Mit virtual hat das in erster Linie wie erwähnt nichts zu tun. Das Problem hat StefanUI weiterhin, falls er eine Funktion erst in einer abgeleiteten Klasse überladen möchte. Deshalb using .

    Ich hab nicht gesagt, dass es am virtual liegt, sondern ich hab ein workaround angeboten, nämlich sowas:

    class B{
            public:
                    void s() {do_s(0);}
                    void s(int i){do_s(i);};
            private:
                    virtual void do_s(int){};
    };
    
    class C : public B {
            private:
                    virtual void do_s(int){};
    };
    

    Aber stimmt natürlich, dass die using-Variante die war, die er wohl hören wollte.



  • Jockelx schrieb:

    Ich hab nicht gesagt, dass es am virtual liegt, sondern ich hab ein workaround angeboten..

    Ich würde das als mehr als ein 'workaround' bezeichnen. Das NVI (non virtual interface idiom) ist meist oder oft auch aus anderen Gründen die richtige Lösung.


Anmelden zum Antworten