2017-06-30 94 views
-1

這裏的優勢是兩個單身,是什麼使第一個可取,因爲雙方將實例對應的類只有一個實例:什麼是使用的shared_ptr與單

第一:

class SharedPointerSingleton { 
public: 
     static std::shared_ptr< SharedPointerSingleton> getSingleton(
    { 
     if(s_pSingleton== 0) s_pSingleton = std::shared_ptr< SharedPointerSingleton>(new SharedPointerSingleton()); 
     return s_pSingleton; 
    } 


private: 
    SharedPointerSingleton(){}; 
    static std::shared_ptr< SharedPointerSingleton> s_pSingleton; 
}; 

第二種:

class PointerSingleton { 
public: 
     static PointerSingleton * getSingleton(
    { 
     if(pSingleton== 0) pSingleton = new PointerSingleton()); 
     return pSingleton; 
    } 


private: 
    PointerSingleton(){}; 
    static PointerSingleton * pSingleton; 
}; 
+3

你絕對應該使用邁爾斯的單例而不是這兩種解決方案。 – Rakete1111

+1

如果你真的想建立一個單身人士(很多人說不),那麼這是你如何做到這一點:https://stackoverflow.com/questions/17712001/how-is-meyers-implementation-of-a- singleton-actually-a-singleton – NathanOliver

+0

其實我需要知道第一個的優點,而不是尋找更好的解決方案 – muaz

回答

2

兩種實施方式各有利弊。第一種解決方案的開銷是使用std::shared_ptr,在某些情況下可能會引起注意。第二種解決方案在程序結束時不會破壞單例對象。雖然內存將在程序生命週期結束時由操作系統釋放,但不正確地銷燬C++對象並不是一個好習慣。它可能直接或間接地釋放未被操作系統清理的資源,例如臨時文件,共享內存等,並且通常會在析構函數中釋放資源。

+0

第二種解決方案的缺點僅適用於單例實際擁有資源的情況。避免使用靜態對象的破壞順序問題也是有利的(例如,不同的單例依賴於對方)。 –

+0

@ChristianHackl第一個解決方案如果其他靜態對象事先獲得了這個單例的'std :: shared_ptr',那麼第一個解決方案沒有銷燬順序問題。如果單身人士確實擁有資源 - 那就是問題。它現在可能不會佔用資源,但後來這種資源可以直接或間接添加。而人,誰補充說,可能很容易不知道析構函數從來沒有調用過。 – Slava

1

程序結束時會發生第二次泄漏(儘管操作系統應該清理內存,您的缺少析構函數調用可能是一個問題)。這可能就是爲什麼有人在頂部添加了一個智能指針。

但是,版本被打破,易受初始化順序問題的影響。

取而代之的是,「正確」的方式來產生一個單是這樣的:

class SharedPointerSingleton 
{ 
    SharedPointerSingleton() = default; 

public: 
    static SharedPointerSingleton& getSingleton(
    { 
     static SharedPointerSingleton instance; 
     return instance; 
    } 
}; 

這方法是安全的,沒有智能指針或動態分配的開銷。現在這個對象是在你第一次請求它的時候精確地構造的,這是非常優越的(除非你想它要在main&之前發生;但是如果你喜歡通過調用這個函數,你仍然可以在命名空間範圍實例化它)。

+0

這個解決方案雖然有問題,但OP的解決方案具有破壞順序。我不認爲OP的解決方案對初始化順序有問題。 – Slava

+0

我更喜歡這個名字。 –

+1

@RickAstley:我永遠不會放棄它。 –

相關問題