RunOrVeith RunOrVeith - 4 months ago 22
C++ Question

What's wrong with my file logger class in C++?

I'm trying to summarize some experimental results in a file.
The results are generated in various C++ classes and files.
I want them to all write to the same file.

For this reason it would be conventient to have a header that defines everything, and then I can just include it in the files that need to write to it. I should be a singleton, so it is not tried to open the same file twice.

It looks like this:

#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


I would now think that in another file I just do:

#include "FileLogger.h"


and then use

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


to write to the file. However, if I try it out, the file is not created; if I create it per hand nothing is written to it.
I do get the output of "got logger", that is called when the logger is accessed via the instance method.
I also noticed that the destructor is never called.

Why is this not working / Is this bad style?

Answer

This code

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

tries to open a file with the literal name ~/results/experiments.txt. Tilde expansion to your home directory is done by your command shell (probably bash). You need to use the actual name of your home directory, for example:

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