這幾天又遇到了靜態(tài)變量析構(gòu)引起的問題,對象析構(gòu)的時(shí)候,定義類的模塊已經(jīng)不能工作了,導(dǎo)致了程序crash。
這在稍大的項(xiàng)目中是一個(gè)非常常見的錯(cuò)誤,只要有多個(gè)模塊,靜態(tài)變量的使用就要非常小心。以前我在寫行車記錄儀的程序時(shí)也碰到過類似的問題,程序是用QT寫的,有一個(gè)靜態(tài)結(jié)構(gòu)析構(gòu)時(shí)調(diào)用了QT的一個(gè)全局對象來打log,QDebug吧,好像。這會(huì)引起段錯(cuò)誤,當(dāng)然啦,退出時(shí)的log也沒能記錄下來。后來發(fā)現(xiàn)原因就是在執(zhí)行這個(gè)析構(gòu)函數(shù)時(shí),QDebug對象已經(jīng)被析構(gòu)了,導(dǎo)致調(diào)用失敗。
這個(gè)問題在Google C++ Style Guide中是這樣建議的,
Objects with static storage duration are forbidden unless they are trivially destructible.
也就是說,除非析構(gòu)函數(shù)中啥也不干,否則就不能定義靜態(tài)類變量。
這條規(guī)則的原因是靜態(tài)變量的析構(gòu)順序是不確定的,所以多個(gè)靜態(tài)變量在析構(gòu)時(shí)的互操作是很容易引起問題的,為減少耦合性,最好的辦法就是不要定義析構(gòu)時(shí)有操作的靜態(tài)變量。
提到靜態(tài)變量,很容易想到單例模式。曾經(jīng)看到有些文章建議(包括著名的《Effective C++》),單例類中的靜態(tài)對象不要在第一次訪問時(shí)new出來,而是直接定義一個(gè)靜態(tài)變量,這樣做的話就也會(huì)存在這個(gè)風(fēng)險(xiǎn),除非這個(gè)靜態(tài)變量對應(yīng)的類析構(gòu)時(shí)不做任何事。
在工程中,單例的需求不可避免。有一個(gè)簡單的辦法可以規(guī)避靜態(tài)變量析構(gòu)帶來的crash風(fēng)險(xiǎn)。
這個(gè)方法就是在單例中用靜態(tài)指針變量,專門寫一個(gè)函數(shù)用于析構(gòu)這個(gè)指針指向的變量,并在工程退出過程中確定不再使用這個(gè)變量的時(shí)候調(diào)用這個(gè)函數(shù)。具體如下:
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;
析構(gòu)函數(shù)里加了個(gè)異常,目的是在free()函數(shù)調(diào)用位置不恰當(dāng)?shù)臅r(shí)候發(fā)出警報(bào)。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動(dòng)首月15元起,快前往官網(wǎng)查看詳情吧
本文名稱:靜態(tài)變量使用的一個(gè)常見錯(cuò)誤-創(chuàng)新互聯(lián)
文章源于:http://chinadenli.net/article10/dgccdo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站建設(shè)、微信公眾號、搜索引擎優(yōu)化、域名注冊、虛擬主機(jī)、App設(shè)計(jì)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容