静态变量使用的一个常见错误-创新互联

这几天又遇到了静态变量析构引起的问题,对象析构的时候,定义类的模块已经不能工作了,导致了程序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://myzitong.com/article/dgccdo.html