简单的C++日志记录类-ostream引用初始化
Simple C++ logging class - ostream reference initialization
我在这里读到了几个类似的问题,这些问题已经得到了回答,但我还没有找到答案,所以在以重复形式结束之前请记住这一点:)。我想要一个带有Print()方法的简单Log对象。如果日志是在没有参数的情况下构建的,那么日志就是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>}’
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;
}
cout
不是ofstream
类型,因此不能将ofstream
引用绑定到它。output_stream
应该是ostream&
类型,这将允许它引用cout
和文件流,因为ofstream
是ostream
的子类。
此外,在用户提供文件名的情况下,引用仍然需要一些东西来引用,不能直接使用它。我建议您存储一个实际的ofstream
对象(或unique_ptr<ofstream>
),并使output_stream
引用它。确保在类定义中的ostream
引用之前声明ofstream
对象,否则,当您尝试绑定初始化列表中的引用时,将有未定义的行为。或者,您可以使它成为一个指针,而不是引用,并在构造函数的主体中分配它。
我建议洗牌filebuf
s或其他streambuf
s。
#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;
}
相关文章:
- 将对象数组的引用传递给函数
- 什么时候在C++中返回常量引用是个好主意
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 为什么在返回 ostream 类时使用引用?
- 包括"lvtocon.h",未定义对'operator<<(std::ostream&, char const*)的引用
- 为什么在重载的 ostream 运算符中引用 lambda 中的向量会导致错误
- 当我编译引用 std::ostream 时,我有一个奇怪的错误弹出
- 将 ostream 作为引用传递时出现错误
- 错误:非静态引用成员"std::ostream&Student::out",无法使用默认赋值运算符
- 为什么重载 ostream 的运算符<<需要一个引用"&"?
- 为什么我们需要在重载>>和<<运算符时返回对 istream/ostream 的引用?
- 返回对此的引用时出现意外的std::ostream输出
- 为什么不能重新分配给对 istream / ostream 的引用
- C++:在重载 ostream >> 时引用 2D 数组元素时崩溃
- 写信给ostream的const引用
- 简单的C++日志记录类-ostream引用初始化
- C++编译器错误,涉及从类型为"std::ostream"的临时引用初始化类型为"std::ostream"的非常量引用
- 创建一个接受ostream引用并输出给它的函数的正确方法是什么?
- 操作符重载- cout和cin——ostream函数,不能被引用——它是一个已删除的函数
- 为什么运算符>>(或<<)重载函数需要接收 i\ostream 引用?