我正在尝试为我在学校的项目创建一个日志类。它需要能够将信息写入标准输出或文件,具体取决于传递的参数。我正在研究如何做到这一点,我偶然发现了一个有类似问题的线程:从 std::cout 或 std::ofstream(file) 获取 std::ostream https://stackoverflow.com/questions/366955/obtain-a-stdostream-either-from-stdcout-or-stdofstreamfile
这个线程和我自己的线程之间的唯一区别是我想在类内部执行它。尽管他们使用了解决方案std::ostream out(buf)
并使用 buf 动态构建 ostream。如何在 Log 类中正确声明这一点,以便仅在输入 Log 构造函数后才能构造“out”对象?
我在下面快速浏览了一下,但我不确定它是否正确,或者我是否走在正确的轨道上。感谢任何帮助,谢谢。
编辑:我希望能够做到out << "Some string" << endl;
当我让这个 Log 类正常工作后。
EDIT2:我现在收到以下新代码的错误error : 'std::basic_ostream<_CharT, _Traits>::basic_ostream() [with _CharT = char, _Traits = std::char_traits<char>]' is protected
// log.h
#include <string>
#include <fstream>
#ifndef LOG_H_
#define LOG_H_
class Log
{
public:
enum Mode { STDOUT, FILE };
// Needed by default
Log(const char *file = NULL);
~Log();
// Writing methods
void write(char *);
void write(std::string);
private:
Mode mode;
std::streambuf *buf;
std::ofstream of;
std::ostream out;
};
#endif
// log.cpp
#include "log.h"
#include <iostream>
#include <stdlib.h>
#include <time.h>
Log::Log(const char *file)
{
if (file != NULL)
{
of.open(file);
buf = of.rdbuf();
mode = FILE;
}
else
{
buf = std::cout.rdbuf();
mode = STDOUT;
}
// Attach to out
out.rdbuf(buf);
}
Log::~Log()
{
if (mode == FILE)
of.close();
}
void Log::write(std::string s)
{
out << s << std::endl;
}
void Log::write(char *s)
{
out << s << std::endl;
}
你创造tmp
with std::ostream tmp(buf);
并将其地址存储在out
with this->out = &tmp;
。然而,tmp
将在构造函数末尾超出范围,并且指针将不再指向有效对象。
你应该做的是out
not a std::ostream*
但只是一个std::ostream
:
std::ostream out;
然后在你的构造函数中,一旦你得到了buf
准备好了,你可以把它给out
通过做out.rdbuf(buf);
.
回复编辑:
The std::ostream
没有默认构造函数 - 它必须采用缓冲区指针。我的错。不过,修复方法很简单。使用构造函数的成员初始化列表来传递空指针(nullptr
在 C++11 中,0
or NULL
在 C++03 中):
Log::Log(const char *file)
: out(nullptr)
{
// ...
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)