C ++ std :: ofstream类成员

时间:2013-06-24 16:13:24

标签: c++ stdout

第一次撰稿人,但我相信我已经正确检查过去的帖子,但找不到有效的解决方案。我正在使用Visual Studio 2012 ...

基本上,我想要做的就是将输出流式传输到对象拥有的日志文件。我对于如何实现这一目标没有任何疑虑,但档案中的任何内容都没有。

据我所知,这个被接受的解决方案应该工作:

#include <fstream>
// classA.h
class A {
private:
    std::ofstream * _logfile;
public:
    A(void);
    void dosomething(void) const;
}

// classA.cpp
#include classA.h
A::A(void) : _logfile(0) {
    std::ofstream output("logfile.txt",std::ofstream::app);
    _logfile = &output;
}

A::dosomething(void) {
    *_logfile << "Print something" << std::endl;
}

// main.cpp
int main() {
A a = new A();
a->dosomething();
}

这个编译好,但只是挂起。我想,最有可能的是,因为输出在ctor结束时消失了。实现此功能的有效方法是什么?其他StackOverflow建议读取导致编译器错误...

谢谢, 克里斯

3 个答案:

答案 0 :(得分:2)

代码具有未定义的行为,因为_logfile在构造A之后是dangling pointer,因为它采用的output地址是A中定义的局部变量A的构造函数:当output的构造函数完成时,_logfile被破坏。然后在do_something()中取消引用std::ofstream,这是未定义的行为,并且可能是挂起的原因。

要解决,只需使用A成员并使class A { private: std::ofstream _logfile; A(const A&); A& operator=(const A&); public: A() : _logfile("logfile.txt",std::ofstream::app) {} void dosomething() { _logfile << "Print something" << std::endl; } }; 不可复制(因为流不可复制,但可移动):

{{1}}

答案 1 :(得分:2)

你有一个指向堆栈上对象的指针,它将在构造函数完成后被删除:

#include classA.h
A::A(void) : _logfile(0) {
    std::ofstream output("logfile.txt",std::ofstream::app);//it's on the stack
    _logfile = &output;//pointer to an object on the stack
}

A::dosomething(void) {
    *_logfile << "Print something" << std::endl;
}

更好地使用:

std::ofstream _logfile;

并在构造函数的初始化列表中初始化它:

A::A(void) : _logfile("logfile.txt",std::ofstream::app){}

答案 2 :(得分:1)

在构造函数中,您将_logfile设置为本地ofstream对象的地址。当构造函数返回时,此对象将被销毁。 _logfile保留为悬空指针,您在dosomething函数中对它的操作会导致未定义的行为。为什么不直接将_logfile声明为常规ofstream对象而不是指针?