Vorwärtsdeklaration von Typdefs?



  • Danke für die Antwort

    pumuckl schrieb:

    Xenya schrieb:

    Wirklich schön ist es aber auch net, wenn dann eine Methde nicht in der Header-Datei vorkommt.

    Wenn du die Methode nur in der cpp brauchst, ist das im Gegenteil nicht besonders schön, wenn sie im Header auftaucht. Das schafft nur unnötige Compilezeit- Abhängigkeiten.
    Typedef-forward-decl gibts leider (noch?) nicht.

    (Weiß jemand wie das in C++0x aussieht? bin grad zu faul nachzuschauen)

    Das heißt umgekehrt, dass eigentlich alle privaten-Methoden aus der .h-Datei raus geworfen werden müssten?



  • Xenya schrieb:

    Deshalb wollte ich mir sowas bauen:

    td temp = (flag)? getAllInformations() : getSpecialInformations();
    

    Das geht leider nicht, da es der Kompilier so umbaut, dass er vorher das temp anlegt und danach per = Operator zuweist.

    Das tut er nicht. Rechts des Zuweisungsoperators steht ein Ausdruck, der als Initialisierung für das Objekt temp verwendet wird. Weder Defaultkonstruktor noch Zuweisungsoperator werden dazu aufgerufen. Der Compiler kann jedoch auswählen, ob er dazu den Kopierkonstruktor aufruft oder gleich temp damit konstruiert.

    Xenya schrieb:

    Probleme macht nur die Methode td getInformations(bool flag). Diese ist ja in der Header-Datei auch definiert. Aber da td eine typedefinition ist, kann ich es nicht vorwärtsdeklarieren - oder geht das? Das wäre toll!!

    Wenn td eine Klasse ist, reicht eine normale Vorwärtsdeklaration im richtigen Namensraum:

    class td;
    


  • Xenya schrieb:

    Deshalb wollte ich mir sowas bauen:

    td temp = (flag)? getAllInformations() : getSpecialInformations();
    

    Das geht leider nicht, da es der Kompilier so umbaut, dass er vorher das temp anlegt und danach per = Operator zuweist.

    Vielleicht geht

    td temp = (flag?getAllInformations:getSpecialInformations)();
    


  • pumuckl schrieb:

    Typedef-forward-decl gibts leider (noch?) nicht.

    (Weiß jemand wie das in C++0x aussieht? bin grad zu faul nachzuschauen)

    Ich glaube kaum, dass es das geben wird, schliesslich gibt man dadurch Typsicherheit auf.

    // Header.hpp
    typedef X;
    
    // A.cpp
    #include "Header.hpp"
    enum X {};
    
    // B.cpp
    #include "Header.hpp"
    class X {};
    

    Was soll X nun sein? Und wie wird es erst bei Templates? Gegeben, wir hätten nur den Header, wäre

    X*
    

    ein gültiger Typ?



  • Danke für eure Antworten.

    Die Umsetzungsvorschläge habe ich (leider mit wenig Erfolg) probiert.

    volkard schrieb:

    Vielleicht geht

    td temp = (flag?getAllInformations:getSpecialInformations)();
    

    Nein geht leider nicht.
    error C2064: Ausdruck ergibt keine Funktion, die 0 Argumente übernimmt

    Nexus schrieb:

    Wenn td eine Klasse ist, reicht eine normale Vorwärtsdeklaration im richtigen Namensraum:

    class td;
    

    td ist ein solches Konstrukt:

    tyedef KlasseImNameSpaceBsp<NochEineKlasseImNamespaceBsp> td
    

    Wenn ich class td; angebe kommt
    error C2371: 'Bsp::td': Neudefinition; unterschiedliche Basistypen



  • Xenya schrieb:

    Das heißt umgekehrt, dass eigentlich alle privaten-Methoden aus der .h-Datei raus geworfen werden müssten?

    Wenn sie nicht auf die Klassenvariablen zugreifen müssen oder virtuell sind, um überschrieben zu werden, wäre das durchaus machbar und wünschenswert.

    Das macht sich vor allem in größeren projekten bezahlt, und wenn die Klasse an vielen stellen benutzt wird:

    Jeder Änderung im Header führt dazu, dass alle Sourcen, die den Header einbinden, neu compiliert werden müssen. Das kann man reduzieren, wenn man Funktionen, die nicht auf die privaten Elemente der Klasse zugreifen müssen, auch nicht als Klassenmethoden, sondern als freie Funktionen in der .cpp deklariert.
    Für ganz extreme Fälle gibt es das "pimpl"-Idiom: die einzig privaten Elemente der Klasse sind ein inneres struct/Klasse (häufig XYZImpl genannt) und ein Pointer darauf (noch häufiger pImpl genannt, daher der Name pimpl-Idiom).
    Das struct wird in der .cpp definiert, alle Daten finden sich darin, und alle Methoden werden über Aktionen auf diesem struct definiert.

    Lektüre:
    http://www.gotw.ca/gotw/007.htm
    http://www.gotw.ca/gotw/024.htm



  • super Danke für Erklärung.

    Schau mir deine Lektüre-Tipps auch noch an



  • Xenya schrieb:

    td ist ein solches Konstrukt:

    tyedef KlasseImNameSpaceBsp<NochEineKlasseImNamespaceBsp> td
    

    Wenn ich class td; angebe kommt
    error C2371: 'Bsp::td': Neudefinition; unterschiedliche Basistypen

    Von Templates hast du nichts gesagt. Dann müsstest du erst das Template deklarieren und dann die Instanziierung als typedef (vorausgesetzt MyClass ist bereits deklariert):

    template <typename T>
    class Template;
    
    typedef Template<MyClass> td;
    


  • Nexus schrieb:

    (vorausgesetzt MyClass ist bereits deklariert):

    Mit Betonung auf deklariert:

    template <typename T>
    class Template;
    
    class MyClass;
    typedef Template<MyClass> td;
    


  • oh, ich sah erst jetzt, dass ihr nochmals geantwortet habt.

    Vielen lieben Dank für eure Mühen.

    ich habe das gleich mal probiert und es funktioniert!


Anmelden zum Antworten