Problem mit __LINE__



  • Ich möchte jedes Objekt, das erstellt wird, "prtokollieren" lassen, in Form einer Zeilennummer im Code. Hier ein Beispiel,
    wie ich es bisher versucht habe:

    Im Konstruktor, der sich in einer separaten cpp-datei befindet, steht:

    Klasse::Klasse() 
    {
        std::cout<<__LINE__<<std::endl;
    }
    

    und wenn ich jetzt irgendwo in main() eine Instanz von Klasse erzeuge, soll auf dem Bildschirm ausgegeben werden,
    in welcher Zeile diese Instanz erzeugt wurde (in der main-funktion). Stattdessen bekomme ich immer die Zeilennummer
    vom Konstruktor, der sich in der separaten cpp-datei (Klasse.cpp) befindet.

    Ich glaube auch nicht, dass es mit __LINE__ funktionieren wird, wenn __LINE__ weiterhin im Konstruktor stehen bleibt, aber das sollte nur eine Demonstration von dem gewesen sein, was ich beabsichtige. Weiss jemand, wie ich das realisieren kann?



  • manfred31 schrieb:

    Ich möchte jedes Objekt, das erstellt wird, "prtokollieren" lassen, in Form einer Zeilennummer im Code. Hier ein Beispiel,
    wie ich es bisher versucht habe:

    Im Konstruktor, der sich in einer separaten cpp-datei befindet, steht:

    Klasse::Klasse() 
    {
        std::cout<<__LINE__<<std::endl;
    }
    

    und wenn ich jetzt irgendwo in main() eine Instanz von Klasse erzeuge, soll auf dem Bildschirm ausgegeben werden,
    in welcher Zeile diese Instanz erzeugt wurde (in der main-funktion). Stattdessen bekomme ich immer die Zeilennummer
    vom Konstruktor, der sich in der separaten cpp-datei (Klasse.cpp) befindet.

    Ich glaube auch nicht, dass es mit __LINE__ funktionieren wird, wenn __LINE__ weiterhin im Konstruktor stehen bleibt, aber das sollte nur eine Demonstration von dem gewesen sein, was ich beabsichtige. Weiss jemand, wie ich das realisieren kann?

    Is auch ganz klar, weil LINE zur Compilezeit durch die entsprechende Zeilennummer im Source ersetzt wird.



  • OK, aber das ist nicht die Antwort auf meine Frage.



  • manfred31 schrieb:

    OK, aber das ist nicht die Antwort auf meine Frage.

    Naja, spontan würde mir da ein Manager einfallen, also so ein Konstrukt:

    // ...
    Klasse* Manager::getInstance(int line) {
       std::cout << "Objekt erzeugt in Zeile: " << line << endl;
       // ... 
       return new Klasse(whatever);
    }
    
    Klasse *k;
    
    k = Manager::getInstance(__LINE__);
    

    Oder halt den Konstruktoren jeweils die __LINE__ mit geben.



  • Hmm, das klingt nicht schlecht, aber dieses Protokollieren sollte möglichst intern ablaufen und die Leute, die dann meine Klasse verwenden, sollten mit sowas nicht konfrontiert werden.



  • Du koenntest __LINE__ als Parameter an den CTor uebergeben. Ist beim Default-CTor
    natuerlich bloed. Da wuesste ich jetzt so grad nichts.

    mfg
    v R



  • vielleicht kannste dir mit sowas ähnlichem behelfen:

    class C
    {
       public: C() {printf ("C ctor\n");}
    };
    
    #define CREATE_C(x) {C C_##x;printf("Object created in line: %d\n",__LINE__);} 
    
    int main ()
    {
        CREATE_C(a);
        CREATE_C(b);
    }
    


  • Oder als Templateargument and den Konstruktor. Und dann noch ein Macro definieren:

    #define myclass myclass<__LINE__>
    

    Dann klappt es auch mit:

    myclass a;
    

    Der Nachteil dabei ist, dass du den Konsruktor von der cpp Datei in den Header verfrachten musst.



  • net schrieb:

    vielleicht kannste dir mit sowas ähnlichem behelfen:

    class C
    {
       public: C() {printf ("C ctor\n");}
    };
    
    #define CREATE_C(x) {C C_##x;printf("Object created in line: %d\n",__LINE__);} 
    
    int main ()
    {
        CREATE_C(a);
        CREATE_C(b);
    }
    

    Und wie soll ich jetzt mit den 2 Objekten arbeiten?



  • interpreter schrieb:

    Und wie soll ich jetzt mit den 2 Objekten arbeiten?

    edit: falsche antwort, sorry.
    richtige: ansprechen kann man sie mit C_ als präfix



  • net schrieb:

    interpreter schrieb:

    Und wie soll ich jetzt mit den 2 Objekten arbeiten?

    edit: falsche antwort, sorry.
    richtige: ansprechen kann man sie mit C_ als präfix

    Nö, eben nicht, weil sie in einem eigenen Block liegen.



  • interpreter schrieb:

    Nö, eben nicht, weil sie in einem eigenen Block liegen.

    achso, ich dummerchen, die klammern waren zuviel.

    class C
    {
       public: 
       C() {printf ("C ctor\n");}
       void f() {printf ("danke interpreter, so geht's jetzt\n");}
    };
    
    #define CREATE_C(x) C C_##x; printf("Object created in line: %d\n",__LINE__); 
    
    int main ()
    {
        CREATE_C(a)
        CREATE_C(b)
        C_a.f();
        C_b.f();
    }
    


  • Danke für f() 🤡



  • optional noch ein

    #ifdef CREATE_C
    #error CREATE_ALREADY_DEFINED
    #else
    #define CREATE_C /* ... */
    #endif
    

    Und das C_ als Prefix würd ich mir abgewöhnen.



  • davie schrieb:

    Und das C_ als Prefix würd ich mir abgewöhnen.

    irgendwas muss da hin wegen des ##. ganz ohne frisst es der präprozessor nicht



  • net schrieb:

    irgendwas muss da hin wegen des ##. ganz ohne frisst es der präprozessor nicht

    Wieso lässt du dann ## nicht einfach weg?

    Irgendwer schrieb:

    Der Nachteil dabei ist, dass du den Konsruktor von der cpp Datei in den Header verfrachten musst.

    Naja, Nachteil ist relativ, da das Template Klassen nun mal so an sich haben.
    Viel schlimmer finde ich, dass du mit solchen defines Namespace Hierarchien auflöst.



  • groovemaster2002 schrieb:

    Wieso lässt du dann ## nicht einfach weg?

    könnte sein, dass es dann nicht das macht, was es soll?
    probier's aus.



  • Es macht schon das was es soll, solange du dir mit anderen defines keine Namenskonflikte baust. Die können dir aber auch mit C_## passieren.



  • groovemaster2002 schrieb:

    Es macht schon das was es soll

    ehrlich? auch mit verschiedenen namen?
    zeig mal bitte wie...



  • #define CREATE_C(x) C x; printf("Object created in line: %d\n",__LINE__);
    
    int main ()
    {
        CREATE_C(a)
        CREATE_C(b)
        a.f();
        b.f();
    }
    

    (ungetestet)


Log in to reply