以下最小代码示例在正常终止时(通过按Enter键)运行正常:
#include <stdio.h>
#include <iostream>
#include <string>
using namespace std;
class SingletonLogClass
{
private:
SingletonLogClass() {}
public:
~SingletonLogClass()
{
LogMessage("~SingletonLogClass()");
}
static SingletonLogClass& getInstance(void)
{
static SingletonLogClass inst;
return inst;
}
void LogMessage(string msg)
{
//printf("%s\n", msg.c_str());
cout << msg << endl;
}
};
int main(int argc, char* argv[])
{
SingletonLogClass::getInstance().LogMessage("This is a message");
getchar();
return 0;
}
当我通过关闭控制台窗口终止程序时,它取决于LogMessage
函数的实现。如果使用printf
实现,一切都很好。但是当使用cout
实现时,我会收到访问冲突。
有人可以解释一下吗?
通过关闭控制台窗口终止程序时到底发生了什么?
为什么它适用于printf
但不适用于cout
?
我正在使用VC ++ 2010。
答案 0 :(得分:6)
cout
是一个全局对象。您的单例实例(在getInstance
静态成员函数中定义为static)也是一个全局对象。
在C ++中,您无法控制构造顺序,也无法控制全局对象的破坏。因此,cout
对象可能会在SingletonLogClass
之前被破坏。由于SingletonLogClass
的析构函数会记录某些内容,因此不再使用cout
(而printf
可以正常使用)。
当程序正常终止(按下回车)并因此退出main
函数时,以及当程序通过关闭shell突然终止时的行为差异来自破坏全局变量的顺序。 您无法控制全局对象的销毁顺序。