2016-08-03 34 views
0

Ich versuche, einige experimentelle Ergebnisse in einer Datei zusammenzufassen. Die Ergebnisse werden in verschiedenen C++ - Klassen und -Dateien generiert. Ich möchte sie alle in die gleiche Datei schreiben.Was ist los mit meiner Datei-Logger-Klasse in C++?

Aus diesem Grund wäre es praktisch, einen Header zu haben, der alles definiert, und dann kann ich es einfach in die Dateien einfügen, die darauf schreiben müssen. Ich sollte ein Singleton sein, also wird nicht versucht, dieselbe Datei zweimal zu öffnen.

Es sieht wie folgt aus:

#ifndef FILELOGGER_H 
#define FILELOGGER_H 

#include <fstream> 

class FileLogger{ 
    std::ofstream *logfile; 
    static FileLogger *s_instance; 

    FileLogger() 
    { 

     logfile = new std::ofstream(); 
     logfile->open("~/results/experiments.txt", std::ios_base::app); 
    } 

    ~FileLogger() 
    { 
     std::cout << "Destructor of logger called" << std::endl; 
     if(s_instance) 
     { 
      logfile->close(); 
      delete logfile; 
      delete s_instance; 
     } 
    } 

public: 
    static std::ofstream *instance() 
    { 
     if (!s_instance) 
     { 
      s_instance = new FileLogger(); 
     } 

     std::cout << "got logger" << std::endl; 

     return s_instance->logfile; 
    } 

}; 

FileLogger *FileLogger::s_instance = 0; 



#endif // FILELOGGER_H 

ich jetzt denken würde, dass ich gerade in einer anderen Datei:

#include "FileLogger.h" 

und verwenden Sie dann

*FileLogger::instance() << "Testoutput" << std::endl; 

in die Datei zu schreiben . Wenn ich es jedoch ausprobiere, wird die Datei nicht erstellt. wenn ich es per Hand erstelle, steht nichts darauf geschrieben. Ich bekomme die Ausgabe von "Got Logger", die aufgerufen wird, wenn der Logger über die Instanzmethode aufgerufen wird. Ich bemerkte auch, dass der Destruktor nie aufgerufen wird.

Warum funktioniert das nicht/Ist das ein schlechter Stil?

+0

Ich werde der Teil „Singleton ist ein Anti-Muster“ überspringen;) Was ist das Ergebnis offen? Ihre Zeile 'FileLogger * FileLogger :: s_instance = 0;' sollte in einer cpp-Datei sein – wasthishelpful

+0

Hat Ihre Anwendung den Schreibzugriff auf die Datei? –

+2

Sie löschen Ihre Instanz in Ihrem Destruktor. Umgekehrt sollte das Löschen Ihrer Instanz Ihren Destruktor aufrufen. –

Antwort

0

Dieser Code

logfile->open("~/results/experiments.txt", std::ios_base::app); 

versucht, eine Datei mit den wörtlichen ~/results/experiments.txt Namen zu öffnen. Die Tilde-Erweiterung zu Ihrem Home-Verzeichnis erfolgt über Ihre Kommando-Shell (wahrscheinlich bash). Sie müssen die tatsächlichen Namen Ihres Home-Verzeichnisses verwenden, zum Beispiel:

logfile->open("/home/yourusername/results/experiments.txt", std::ios_base::app); 
+0

Ich akzeptiere das (obwohl ich es selbst herausgefunden habe, siehe Kommentare zu der Frage) – RunOrVeith

0

Lassen Sie den "Header" -Trick los. Deklarieren Sie einfach eine Klasse in einer Kopfzeile, implementieren Sie sie in einer cpp-Datei, und verwenden Sie einen statischen Zähler oder einen statischen Booleschen Wert, um mehrere Instanziierungen zu verhindern. Ich denke, das ist viel einfacher als diese nur-Kopf-Singleton Magie.

+1

In der Tat. In der Tat, warum sollten Sie es überhaupt zählen? Erklären Sie einfach so viele, wie Sie benötigen (was eins ist) und lassen Sie es dabei gehen. Seien Sie nicht paranoid, wenn sich jemand in der Nacht in Ihr Haus schleicht und in Ihrem Code ein paar mehr hinzufügt. –

+1

Einverstanden. Wenn Sie nur 2 Objekte einer bestimmten Klasse benötigen, würden Sie kein "Gemini" -Muster verwenden .... Obwohl gesagt wird, dass Sie bei der Programmierung entweder 0, 1 oder unendlich viele Objekte zulassen sollten ... –

+0

Aber wie würde das behoben? OPs Problem? – juanchopanza