2

第一次贡献者,但我相信我已经正确检查了过去的帖子并且没有找到有效的解决方案。我正在使用 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 建议读取会导致编译器错误...

谢谢,克里斯

4

3 回答 3

5

代码在构造之后_logfile具有未定义的行为,A因为它正在获取的地址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;
    }
};
于 2013-06-24T16:16:25.527 回答
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){}
于 2013-06-24T16:21:25.183 回答
1

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

于 2013-06-24T16:16:23.527 回答