这几天又遇到了静态变量析构引起的问题,对象析构的时候,定义类的模块已经不能工作了,导致了程序crash。
10年积累的网站建设、网站设计经验,可以快速应对客户对网站的新想法和需求。提供各种问题对应的解决方案。让选择我们的客户得到更好、更有力的网络服务。我虽然不认识你,你也不认识我。但先建设网站后付款的网站建设流程,更有浔阳免费网站建设让你可以放心的选择与我们合作。这在稍大的项目中是一个非常常见的错误,只要有多个模块,静态变量的使用就要非常小心。以前我在写行车记录仪的程序时也碰到过类似的问题,程序是用QT写的,有一个静态结构析构时调用了QT的一个全局对象来打log,QDebug吧,好像。这会引起段错误,当然啦,退出时的log也没能记录下来。后来发现原因就是在执行这个析构函数时,QDebug对象已经被析构了,导致调用失败。
这个问题在Google C++ Style Guide中是这样建议的,
Objects with static storage duration are forbidden unless they are trivially destructible.
也就是说,除非析构函数中啥也不干,否则就不能定义静态类变量。
这条规则的原因是静态变量的析构顺序是不确定的,所以多个静态变量在析构时的互操作是很容易引起问题的,为减少耦合性,最好的办法就是不要定义析构时有操作的静态变量。
提到静态变量,很容易想到单例模式。曾经看到有些文章建议(包括著名的《Effective C++》),单例类中的静态对象不要在第一次访问时new出来,而是直接定义一个静态变量,这样做的话就也会存在这个风险,除非这个静态变量对应的类析构时不做任何事。
在工程中,单例的需求不可避免。有一个简单的办法可以规避静态变量析构带来的crash风险。
这个方法就是在单例中用静态指针变量,专门写一个函数用于析构这个指针指向的变量,并在工程退出过程中确定不再使用这个变量的时候调用这个函数。具体如下:
class Singleton
{
public:
static Singleton* getInstance()
{
if(pInstance == nullptr)
{
pInstance = new Singleton();
}
return pInstance;
}
void free()
{
if (pInstance != nullptr)
{
delete pInstance;
pInstance = nullptr;
}
}
private:
static Singleton* pInstance;
private:
Singleton() {}
~Singleton()
{
if (pInstance != nullptr)
{
throw("Singleton object used after free().");
}
}
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
};
Singleton* Singleton::pInstance = nullptr;
析构函数里加了个异常,目的是在free()函数调用位置不恰当的时候发出警报。
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧
网页名称:静态变量使用的一个常见错误-创新互联
网页路径:http://lswzjz.com/article/dgccdo.html