I've read several similar questions here that have been answered, but I don't grok yet, so please bear that in mind before closing as duplicate :). I want a simple Log object with a Print() method. If Log is constructed with no parameters, logging is to cout. Otherwise, parameters describe a file to which logging is done.
(I suspect part of the problem is understanding the relationship between all the stream classes.)
When compiled, error is:
Log.cpp:11:23: error: invalid initialization of reference of type ‘std::ofstream& {aka std::basic_ofstream<char>&}’ from expression of type ‘std::ostream {aka std::basic_ostream<char>}’
Log.h:
#ifndef LOG_H
#define LOG_H
#include <string>
#include <fstream>
class Log {
public:
Log();
Log(const char*, const char*);
void Print(const char* msg,...);
private:
// instance contains a reference to ostream
std::ofstream& output_stream;
};
#endif
Log.cpp:
#include "Log.h"
#include <iostream>
using std::cout;
using std::endl;
#include <string>
using std::string;
#include <fstream>
// Constructor w/no parms = log to cout
Log::Log() :
output_stream(cout)
{}
// Constructor w/parms = log to file
Log::Log(const char* dir, const char* file) {
string output_file_name = string(dir) + "/" + string(file);
output_stream.open(output_file_name.c_str(), std::ofstream::out);
}
// Print() sends output to the stream (we'll do printf semantics later)
void
Log::Print(const char* msg,...) {
output_stream << msg << endl;
}
coutis not of typeofstream, so you cannot bind anofstreamreference to it.output_streamshould be typeostream&instead, which will allow it to refer to eithercoutand a file stream, sinceofstreamis a subclass ofostream.Also, in the case that the user provides a filename, you still need something for the reference to refer to, you can't just use it as is. I recommend that you store an actual
ofstreamobject, (or aunique_ptr<ofstream>), and makeoutput_streamrefer to it. Make sure you declare theofstreamobject before theostreamreference in your class definition, otherwise you will have undefined behavior when you try to bind the reference in the initialization list. Or you can make it a pointer, instead of a reference, and assign it in the body of the constructor.