首先,我看到许多帖子说从ostream
派生一个类是非平凡的,但那也是可以理解的,因为'ostream'本身需要为流提供缓冲。
如何从fstream
或ofstream
派生?我认为这应该是直截了当的,因为这些基类确实设置了缓冲区并从它们派生仅仅实例化fstream
并因此封装它。
现在我正在创建一个类似于此(头文件)的日志文件
class lfstream : public std::ofstream
{
public:
lfstream();
~lfstream();
void log(const std::string &text);
protected:
std::ofstream logfile;
char logfname[32];
};
extern lfstream ls;
相应的cpp文件是
lfstream ls; // global object of log file so I can write to it
lfstream::lfstream() : logfname("Mylog.txt")
{
logfile.open(logfname, std::ios_base::out | std::ios_base::app);
}
lfstream::~lfstream()
{
}
void lfstream::log(const std::string &text)
{
logfile << text;
}
现在在main()函数中
int main(int argc, char * argv)
{
// this is for camparison, << operator works on ofstream
std::ofstream stockstream("ostream_test.txt");
stockstream << "<< test ostream" << std::endl; // works
// But << doesn't work on my derived class which is also a stream
ls << "<< test ls stream"; // why this doesn't go into the file?
ls.log("This works"); // but this does
}
所以我的第一个问题是,来自ostream
,如上所述,好吗?其次,为什么<<
对派生类不起作用?
更新
所以我的实施是错误的。我现在使用成员变量ofstream
对象,现在构造函数就像这样:
lfstream::lfstream() : logfname("debug_log.txt"), std::ofstream(logfname )
{
}
但是我现在如何实现log()函数?
更新2
我的日志会实际打印更多数据并相应地对其进行格式化。这就是我没有实例化ofstream
void lfstream::log(const std::string &text)
{
const time_t ctt = time(0);
int threadID = GetCurrentThreadId();
logfile << std::setw(40) << std::left << text << " thread id = " << threadID << "\t" << asctime(localtime(&ctt)); // << std::endl;
}
这意味着我可以致电ls.log(...)
并进行格式化。
答案 0 :(得分:1)
我发布了答案。我原来的代码是有缺陷的,因为我同时使用组合和继承(感谢指出这一点的评论)。两种方法都提供了不同形式的解决方案,因此首先要确定使用哪种解决方案。
<强>组合物强>
我的班级宣布std::ofstream logfile;
所以我没有必要从ofstream
派生出来将工作委托给其成员变量。这是作文。
<强>继承强>
由于我的班级来自std::ofstream
,我没有必要声明相同的成员变量。删除后,该类现在看起来像下面。我的想法是模仿ofstream
,实现相同的构造函数并在其中实例化基类ofstream
类(我只实现了一个构造函数)。
lfstream::lfstream(const std::string& logfilename) : _logfname(logfilename),
std::ofstream(logfilename)
{
}
lfstream::~lfstream()
{
}
void lfstream::log(const std::string &text)
{
*this << text;
}
这确实解决了原始问题,现在<<
适用于我的派生类。