logbuch klasse



  • hallo,
    ich habe hier folgendes problem:

    ich habe eine klasse log entworfen die das schreiben in deine datei als auch die ausgabe auf der konsole übernimmt. die klasse log ist ein globales logbuch.

    damit alle anderen klassen auf das logbuch zugreifen können,
    habe ich einen zeiger auf das logbuch als variable in den klassen angelegt,
    und das schreiben in das logbuch klappt.

    allerdings gibt es zwei sachen die mir nicht gefallen:

    ist der zeiger uninitialisiert stürzt das programm ab,
    also brauche ich eine weitere funktion die überprüft ob der zeiger != nullptr ist. dies ist aber schlecht, da ich dann im logbuch nicht mehr sehe aus welcher zeile der aufruf kam.

    ändere ich den konstrukter der klasse ab, das zwingend das logbuch übergeben werden muss, damit brüchte ich dann das "extra" fehlerhandling (nullptr) nicht mehr, kann ich diese klasse nur mit new anlegen richtig?
    als membervariable ohne new funktioniert das ganze nicht, richtig?

    ich hoffe ihr versteht mein anliegen, sry bin noch relativ neu in c++

    vielen dank für die antworten!

    grüße



  • cn00py schrieb:

    ändere ich den konstrukter der klasse ab, das zwingend das logbuch übergeben werden muss, damit brüchte ich dann das "extra" fehlerhandling (nullptr) nicht mehr, kann ich diese klasse nur mit new anlegen richtig?
    als membervariable ohne new funktioniert das ganze nicht, richtig?

    Nein. Du übergibst dem Konstruktor einfach einen Zeiger auf das Logbuch, besser noch, Du arbeitest mit einer Referenz, statt mit einem Pointer.

    Das Logbuch muss natürlich existieren, bevor Du die Klasseninstanzen konstruierst.



  • Belli schrieb:

    Nein. Du übergibst dem Konstruktor einfach einen Zeiger auf das Logbuch, besser noch, Du arbeitest mit einer Referenz, statt mit einem Pointer.

    Das Logbuch muss natürlich existieren, bevor Du die Klasseninstanzen konstruierst.

    hallo,
    wie sieht das aus?

    ich mache das normalerweise so,
    allerdings funktioniert das so ja nicht da die klasse a zwingend die logbuch referenz brauch, wie kann ich die also übergeben?

    danke

    class test
    {
        test(log &value);
        do_something(void);
    }
    
    class test2
    {
        test2(log &value);
    private:
         test a;
    }
    


  • cn00py schrieb:

    hallo,
    wie sieht das aus?

    ich mache das normalerweise so,
    allerdings funktioniert das so ja nicht da die klasse a zwingend die logbuch referenz brauch, wie kann ich die also übergeben?

    danke

    Ungetestet:

    class test
    {
      public;
        test(log &value) : value(value);
        do_something(void);
      private:
       log &value;
    }
    
    class test2
    {
        test2(log &value) : value(value), a(value);
    private:
         log &value;
         test a; 
    }
    
    int main()
    {
    ...
    log LogBuch;
    ...
    test2 Test(LogBuch);
    ...
    
    }
    


  • Hallo,

    ich empfehle dir, logging durch freie Funktionen oder eine freie Funktion, die dir eine Log-Instanz zurück gibt, zu realisieren.



  • Jockelx schrieb:

    Hallo,

    ich empfehle dir, logging durch freie Funktionen oder eine freie Funktion, die dir eine Log-Instanz zurück gibt, zu realisieren.

    Wie meinst du das genau?
    Verstehe ich leider nicht ganz..
    also keine eigene klasse sonder einfach als funktion zu realisieren?

    aber das logging hat einstellungen, datei, pfad, log level, etc.
    das wird schwierig ohne klasse oder?

    danke



  • Nein, Log-Klasse ist schon gut, aber jeder Klasse ein Log-memeber zu geben ist nicht gut.

    Besser zB sowas:

    Log* getLog()
    {
      static Log log;
      return &log;
    }
    // oder 
    LogZBWarning(const std::string& msg)
    {
      getLog()->log(Warning, msg);....
    }
    // Und in den Klassen nur die Funktion aufrufen oder halt den globlen Log holen
    


  • Alternativ könntest du auch ein fertiges Log-Framework nutzen, z.B. https://github.com/gabime/spdlog. Dann kannst du dir in jeder Klasse mit spdlog::get("logger name") den entsprechenden Logger holen.



  • Jockelx schrieb:

    Nein, Log-Klasse ist schon gut, aber jeder Klasse ein Log-memeber zu geben ist nicht gut.

    Besser zB sowas:

    Log* getLog()
    {
      static Log log;
      return &log;
    }
    // oder 
    LogZBWarning(const std::string& msg)
    {
      getLog()->log(Warning, msg);....
    }
    // Und in den Klassen nur die Funktion aufrufen oder halt den globlen Log holen
    

    Vielen vielen dank,
    mensch das ich da nicht früher drauf gekommen bin.
    danke so wird es gemacht!

    grüße



  • Wenn ich das hier lese höre ich wie es im Hintergrund murmelt: Singleton, Singleton ...



  • Du weißt nichts über die Log-Klasse, weißt aber, dass es ein Singleton sein sollte?
    Aha...



  • Naja, der Beispiel Code kommt schon recht nah an das Konzept eines Singletons dran.



  • Welcher Beispielcode?
    Hier steht keine einzige Zeile Code von der Log-Klasse.



  • Dieses hier lässt schon schlüsse ziehen...

    cn00py schrieb:

    Jockelx schrieb:

    Nein, Log-Klasse ist schon gut, aber jeder Klasse ein Log-memeber zu geben ist nicht gut.

    Besser zB sowas:

    Log* getLog()
    {
      static Log log;
      return &log;
    }
    // oder 
    LogZBWarning(const std::string& msg)
    {
      getLog()->log(Warning, msg);....
    }
    // Und in den Klassen nur die Funktion aufrufen oder halt den globlen Log holen
    

    Vielen vielen dank,
    mensch das ich da nicht früher drauf gekommen bin.
    danke so wird es gemacht!

    grüße



  • Das ist wie ich gerade die Log-Klasse nutze.
    Und weil ich das gerade zufällig so mache, soll die Log-Klasse jetzt so geändert werden, dass das jeder zu jeder Zeit so machen muss?
    Singletons haben eh schon einen schlechten Ruf und wenn man Sie so versteht, dann auch zu Recht.



  • Wie ich bereits schrieb, es kommt nah an das Konzept des Singltons ran. Nicht, dass es eins wäre.

    Aus dem Code geht natürlich nicht hervor, dass man nicht auch andere Instanzen der Log Klasse erstellen kann und wenn man das über Library Grenzen hinweg verwendet hat man auch in jeder Library eine eigene Instanz. Aber es kommt trotzdem dem Konzept recht nahe.



  • Singletons haben eh schon einen schlechten Ruf ...

    Davon habe ich zwar auch schon gehört, kann das aber nicht wirklich nachvollziehen.

    Wie ich bereits schrieb, es kommt nah an das Konzept des Singltons ran. Nicht, dass es eins wäre.

    Ob es wirklich eins sein sollte, hängt wohl davon ab, ob es mehrere Instanzen davon geben darf und ob man das ggf. programmtechnisch oder durch Disziplin erreichen will.

    Eine Parallele sehe ich hier:
    Die Klasse hat einen privaten Konstruktor (oder ist komplett statisch).

    Es gibt eine statische Methode get_Log() oder get_Instance(),
    die ggf. die Klasse erzeugt, oder wenn bereits vorhanden, nur den Zeiger darauf zurück gibt.


Log in to reply