简体   繁体   中英

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?

Let go of the 'header' trick. Just declare a class in a header, implement it in a cpp file, and use a static counter or static boolean to prevent multiple instantiations. I think that's much simpler than this header-only singleton magic.

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM