亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

聲明為GetInstance方法的靜態變量的Singleton實例,它是線程安全的嗎?

聲明為GetInstance方法的靜態變量的Singleton實例,它是線程安全的嗎?

慕虎7371278 2019-12-25 10:50:59
我已經看到了Singleton模式的實現,其中實例變量在GetInstance方法中被聲明為靜態變量。像這樣:SomeBaseClass &SomeClass::GetInstance(){   static SomeClass instance;   return instance;}我看到這種方法有以下積極方面:代碼更簡單,因為只有第一次調用GetInstance時,編譯器才負責創建此對象。該代碼更加安全,因為沒有其他方法可以獲取對實例的引用,但是可以使用GetInstance方法,并且沒有其他方法可以更改實例,但是可以在GetInstance方法內部進行。這種方法的負面影響是什么(除了這不是面向對象的)?這是線程安全的嗎?
查看完整描述

3 回答

?
慕哥6287543

TA貢獻1831條經驗 獲得超10個贊

在C ++ 11中,它是線程安全的:


§6.7[stmt.dcl] p4如果在初始化變量的同時控件同時輸入聲明,則并發執行應等待初始化完成。


在C ++ 03中:


在g ++下,它是線程安全的。

但這是因為g ++顯式添加了代碼來保證它。

一個問題是,如果您有兩個單例,并且它們在構造和銷毀過程中相互嘗試使用。


閱讀本文: 查找C ++靜態初始化順序問題


此問題的一個變體是,是否從全局變量的析構函數訪問單例。在這種情況下,單例無疑已被破壞,但是get方法仍將返回對被破壞對象的引用。


有很多解決方法,但是它們很雜亂,不值得做。只是不要從全局變量的析構函數訪問單例。


一個更安全的定義但很丑陋:

我敢肯定您可以添加一些適當的宏來整理一下


SomeBaseClass &SomeClass::GetInstance()

{

#ifdef _WIN32 

Start Critical Section Here

#elif  defined(__GNUC__) && (__GNUC__ > 3)

// You are OK

#else

#error Add Critical Section for your platform

#endif


    static SomeClass instance;


#ifdef _WIN32

END Critical Section Here

#endif 


    return instance;

}


查看完整回答
反對 回復 2019-12-25
?
catspeake

TA貢獻1111條經驗 獲得超0個贊

根據規范,這也應在VC ++中工作。有人知道嗎?


只需添加關鍵字volatile。如果msdn上的文檔正確,則可視c ++編譯器應生成互斥體。


SomeBaseClass &SomeClass::GetInstance()

{

   static volatile SomeClass instance;

   return instance;

}


查看完整回答
反對 回復 2019-12-25
  • 3 回答
  • 0 關注
  • 756 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號