[英]Explanation of C++ singleton code
最近有人問我有關c ++中的單例設計模式。 我不知道它到底是什么功能或什么時候需要它,所以我嘗試了一下。 我主要在stackoverlow上找到了很多答案,但是我很難理解這些問題和答案中提到的代碼。 我知道單身人士應該滿足的以下特性,如果我錯了,請糾正我。
It is used when we need to make one and only one instance of a class.
這在我腦海中引發了以下問題
Does this mean that it can be created only once or does this mean that it can be
created many times but at a time only one copy can exist?
現在開始執行。 從這里復制
class S
{
public:
static S& getInstance()
{
static S instance; // Guaranteed to be destroyed.
// Instantiated on first use.
return instance;
}
private:
S() {}; // Constructor? (the {} brackets) are needed here.
// Don't forget to declare these two. You want to make sure they
// are inaccessible otherwise you may accidentally get copies of
// your singleton appearing.
S(S const&); // Don't Implement
void operator=(S const&); // Don't implement
};
請解釋:
1.為什么我們必須使getinstace()函數成為靜態函數?
這是獲取實例的唯一方法-靜態意味着您不需要現有實例來調用它。 如果您需要一個實例來獲取一個實例,那么您將陷入困境。
那是因為你可以寫成靜態的:
S::getinstance().blah();
如果不是靜態的,則需要編寫
S& s_instance = ....
s_instance.getInstance().blah();
但是,由於您已經有一個實例,因此無需調用getInstance
。 如果通過getInstance
獲得實例的唯一方法是如何獲得該實例的?
2,為什么需要S(S const&); 構造函數?
你不知道 它是有意私有的,沒有實現,因此調用它會導致錯誤。 如果未明確將其私有化且未實現,則編譯器將為您創建一個默認的公共副本構造函數。這意味着人們可以編寫
S scopy(S::getInstance());
他們最終得到了S的新實例-打破了單例語義。
3. void operator =(S const&)是什么? 做?
與2相同。它未實現且為私有,因此調用它會導致錯誤。 同樣,如果您不明確,編譯器將為您創建一個默認實例,在這種情況下,用戶可以通過它獲得一個新實例。
S scopy = S::getInstance();
4.為什么我們不實現最后兩個功能?
如果您可以復制/分配單例,它將失去其單例狀態。 任何時候僅應存在一個單例。
但是請注意,單例通常被認為是反模式 。 你不想要的東西沒有一個很好的理由來使用。 了解它附帶的線程問題也是很明智的……而且,最重要的是,您會遇到一些靜態初始化順序的失敗,並通過一些實現它的方式遇到了麻煩。 (代碼中的方法還可以,但是很容易出錯。)
1)是的。 該函數實際上使您可以獲取S
單個實例。 因此,您調用S::getInstance()
。 如果不是靜態的,那么您將無法做到這一點。
2、3和4)請注意,構造函數和operator=
是私有的。 這是為了防止某人創建S
另一個實例,從而使單例狀態無效。
與其構造自己的S
, S::getInstance()
使用S::getInstance()
獲取單個實例。
是的,它應該是靜態的,因為它不需要實例指針。 使其變為非靜態將無濟於事。
是的,我們確實需要至少一個函數構造函數。 初始實例需要以某種方式進行 。 創建第一個實例時,私有構造函數將強制外部用戶通過getInstance
獲取實例。
為該實例分配新值時,將使用賦值運算符operator=(S const&)
。 對於單例來說這沒有任何意義,因此被聲明為私有,並且沒有實現。 沒有人可以使用它。
不,復制構造函數和賦值運算符必須既是私有的,又沒有實現。 這是C ++習慣用法,表示: 不能復制此類或將其分配給 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.