1

我在这里阅读了几个已经回答的类似问题,但我还没有理解,所以在关闭之前请记住这一点:)。我想要一个带有 Print() 方法的简单 Log 对象。如果 Log 是不带参数构造的,则 logging 是 cout。否则,参数描述了一个完成日志记录的文件。

(我怀疑部分问题是理解所有类之间的关系stream。)

编译时,错误是:

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>}’

日志.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

日志.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;
}
4

2 回答 2

2

cout不是 type ofstream,所以你不能绑定ofstream对它的引用。 output_stream应该是 typeostream&而不是,这将允许它引用cout文件流和文件流,因为ofstream它是ostream.

此外,在用户提供文件名的情况下,您仍然需要一些东西供参考参考,您不能按原样使用它。我建议您存储一个实际ofstream对象(或 a unique_ptr<ofstream>),然后output_stream引用它。确保在类定义中的引用之前ofstream声明对象,否则当您尝试在初始化列表中绑定引用时将出现未定义的行为。或者,您可以将其设为指针,而不是引用,并将其分配到构造函数的主体中。ostream

于 2013-08-31T20:34:44.897 回答
0

我建议改组filebufs 或 other streambufs。

#include <string>
#include <ostream>
#include <fstream>

class Log {

public:
    Log();
    Log(const char*, const char*);

    void Print(const char*  msg,...);

private:
    // instance contains a reference to ostream
    std::ostream  output_stream;
    std::ofstream _file;
};

cpp

#include <iostream>
#include <string>
#include <fstream>

// Constructor w/no parms = log to cout
Log::Log()
    : output_stream(std::cout.rdbuf())
{}

// Constructor w/parms = log to file
Log::Log(const char* dir, const char* file) 
    : output_stream(nullptr)
{
    std::string output_file_name = std::string(dir) + "/" + std::string(file);
    _file.open(output_file_name.c_str(), std::ofstream::out);
    output_stream.rdbuf(_file.rdbuf());
}

// Print() sends output to the stream (we'll do printf semantics later)
void Log::Print(const char* msg,...) {
    output_stream << msg << std::endl;
}
于 2013-08-31T20:51:11.767 回答