Muss bei einer abstrakten Klasse jede Funktion überladen werden?



  • Okay, danke!
    Wenn ich eine Funktion überlade, muss ich die dann so überladen:

    class XFace : public IFace
    {
    public:
        virtual void Func1();
        // oder so?
        void Func1();
    };
    

    Gruß



  • Ist absolut identisch. Eine Funktion die einmal als virtual deklariert wurde, bleibt auch in den abgeleiteten Klassen virtual, das kannst du nicht mehr ändern.
    Persönlcih bevorzuge ich die erste Methode, damit klar ist, dass diese Funktion eine andere überschreibt.



  • Muss bei einer Interfaceklasse (= abstrakte Klasse) jede Funktion überladen werden?

    Warum sollte man das tun?
    Eine Klasse ist abstrakt, sobald eine Funktion pure virual ist. Dabei heißt abstrakt lediglich, dass keine Instanzen dieser Klasse gebildet werden können.

    Ob du da jetzt eine Funktion überlädst, sollte egal sein.

    PS: Ich hoffe ich erzähle hier keinen Unsinn. Wenn dem so ist, möge man mich bitte aufklären.



  • Abstrakt schrieb:

    Muss bei einer Interfaceklasse (= abstrakte Klasse) jede Funktion überladen werden?

    Warum sollte man das tun?
    Eine Klasse ist abstrakt, sobald eine Funktion pure virual ist. Dabei heißt abstrakt lediglich, dass keine Instanzen dieser Klasse gebildet werden können.

    Ob du da jetzt eine Funktion überlädst, sollte egal sein.

    PS: Ich hoffe ich erzähle hier keinen Unsinn. Wenn dem so ist, möge man mich bitte aufklären.

    Durch das Überladen der Funktion entfernst du diesen "pure virtual" Status, die Klasse ist also nicht mehr abstrakt. Darauf wollte er hinaus.

    Eine Klasse die von diesem "Interface" erbt, erbt auch alle pure virtual Funktionen, ist daher auch abstrakt. Zuerst müssen alle pure virtual Funktionen überladen werden.



  • Merci beaucoup!

    Eine weitere Frage, die dieses Thema betrifft:
    Möchte ich beispielsweise eine Klasse Color schreiben, die jedem zugänglich sein soll (man kann mein Programm via Addons erweitern), soll ich dann trotzdem die Definitionen in der .hpp belassen und die Implementation in die .cpp tun, oder beides in die .hpp ? Ich frage daher, da ich möchte, dass man nur #include "Color.hpp" machen muss, und nicht noch die .cpp 's einzeln zum Projekt (Beispielsweise bei VC++) hinzufügen muss, um keinen Linkerfehler zu erhalten.

    Gruß



  • theliquidwave schrieb:

    Merci beaucoup!

    Eine weitere Frage, die dieses Thema betrifft:
    Möchte ich beispielsweise eine Klasse Color schreiben, die jedem zugänglich sein soll (man kann mein Programm via Addons erweitern), soll ich dann trotzdem die Definitionen in der .hpp belassen und die Implementation in die .cpp tun, oder beides in die .hpp ? Ich frage daher, da ich möchte, dass man nur #include "Color.hpp" machen muss, und nicht noch die .cpp einzeln zum Projekt (Beispielsweise bei VC++) hinzufügen muss, um keinen Linkerfehler zu erhalten.

    Gruß

    Wenn du die Implementation deiner Klasse in einer eigenen Übersetzungseinheit hast musst du die resultierende Objektdatei auch zu den Projekten dazulinken, in denen du die Klasse benutzt.



  • Du verwechselst gerade Definition mit Deklaration.

    Deklaration in die Header-Datei: void Foo();
    Definition in die Source-Datei: void Foo() { }

    Die Definitionen solltest du in der Source-Datei belassen, denn wenn sie in der Header-Datei stehen, kannst du diese Header-Datei nur einmal einbinden. Denn sonst brichst du die one definition rule (alles darf nur einmal definiert sein).

    Wenn du jetzt nicht willst, dass man die Source-Datei mit in ein anderes Projekt kopieren muss, so kannst du auf Bibliotheken (Libraries) ausweichen. Dann muss das entsprechende Projekt gegen diese Bibliothek linken. Solche Bibliotheken sind je nach System unterschiedlich aufgebaut und sie sind nicht einmal unter verschiedenen Compilern kompatibel (Programm nutzt Compiler A, Bibliothek wurde mit Compiler B erstellt -> Kabuff).



  • Das heißt, ich sollte die Implementation gleich mit in die .hpp packen, falls ich das so machen möchte, richtig? (Ich hoffe ich hab das richtig verstanden)

    Edit: Ach so. Stimmt, das habe ich in der Tat verwechselt. Dann werde ich das wohl so mit der Library lösen 😉

    Gruß



  • Du meinst übrigens überschreiben, nicht überladen.



  • Argh, was ist heute blos los mit mir.
    Natürlich meine ich überschreiben 😉

    Gruß


  • Mod

    theliquidwave schrieb:

    Hallo.
    Muss bei einer Interfaceklasse (= abstrakte Klasse) jede Funktion überladen werden?

    Nein, Funktionsüberladung in abgeleiteten Klassen verdeckt die entsprechende Deklaration der Interfaceklase, macht die abgeleitete Klasse aber nicht nicht-abstrakt. Der korrekte Begriff hier ist Überschreiben (override).



  • Ich kenne nur einen Grund, warum man Definitionen in Header packen muss, und das sind Templates. Schreib deinen Code compilerunabhängig und kompiliere ihn in MSVC++ und GCC, dann hast du eh schon über 70% der Entwickler auf deiner Seite. Für den GCC lieferst du dann jeweils eine *.hpp und eine *.a-Datei (statische Library) bzw. eine *.so (Linux Dynamische Library) oder du machst eine *.o-Datei (Objektcodedatei), für MSVC++ machst du entweder eine *.hpp mit einer *.lib (Statische Library) oder einer *.obj (Objektcodedatei) bzw. eine *.dll (Dynamische Library für Windows) mit oder ohne *.lib...

    Da gibt es wirklich sehr viele Möglichkeiten und viele Libraries und Softwarekomponenten werden mit verschiedenen Compilern gebaut.



  • Hi.
    Wenn ich folgendes Interface habe:

    class IFace
    {
    public:
        virtual void Bla(IOtherFace *pFace) = 0;
    };
    

    Und folgende Implementation:

    class CFace : public IFace
    {
    public:
        virtual void Bla(COtherFace *pFace);
    };
    

    Ist das eine valide Überschreibung? Natürlich ist COtherFace als class COtherFace : public IOtherFace defklariert.

    Gruß



  • *push*



  • theliquidwave schrieb:

    Ist das eine valide Überschreibung?

    Nein. Und unterlasse das pushen (Zumal der Thread noch keinen Tag alt ist).


Anmelden zum Antworten