2013-11-28 94 views
0

我試圖用C++ 11實現一個類似單例的對象。我從其他用戶那裏得到了這個例子。對象的單個實例

它用構造函數和拷貝構造函數private和default創建一個對象,以及一個返回靜態對象的instance()函數。

據我所知,這應該防止創建這個對象的兩個實例。但正如你可以在我的main.cpp中看到的那樣,我創建了兩個實例並編譯並運行。

我的對象創建是錯誤的還是什麼?我不明白。

object.hpp:

#ifndef OBJECT_H 
#define OBJECT_H 

#include <iostream> 
using namespace std; 

class Object 
{ 
private: 
    Object() = default; 
    Object(const Object&) = delete; 
public: 
    // Singleton in C++11 
    static Object& instance() { static Object z; return z; } 
}; 

#endif // OBJECT_H 

main.cpp中:

#include "object.hpp" 

int main() 
{ 
    Object* object = new Object(); 
    object->instance(); 

    Object* object2 = new Object(); 
    object->instance(); 

    return 0; 
} 
+0

也許這是'= default'奇怪的規則之一。如果我使用Object(){}而不是Object()= default;'我得到想要的結果('new'不起作用。) – alfC

+0

精確地使用術語:「它用構造函數創建一個對象和副本......「。其實它創建一個類:)。也許命名一個類「對象」不是最好的主意,因爲這個) –

+0

你說得對,alfC,如果我使用Object(){},我的編譯器也會抱怨'new'命令。有更多關於'= default'的怪異規則嗎? – Smii

回答

1

首先你的代碼main不會編譯。 Object默認的構造函數是私人的,所以你將無法做到:

Object * object = new Object();

第二,由於instance()是靜態的(指不涉及任何實例)也沒有必要從對象調用它,類名足以:

對象& theInstance =對象::實例();

最後,實例的代碼是:

static Object& instance() 
{ 
    static Object z; 
    return z; 
} 

這是確定的。 C++函數中的一個變量static意味着該對象被立即執行一次:該函數第一次運行。那麼z將不會在函數結束時被銷燬(與其他所謂的局部變量相反),並將在下次調用instance時重新使用。

所以在instance第一次調用:

  • z創建
  • z z爲返回

在接下來的電話:

  • z返回

單例是一個類,它意味着只會創建一個實例。您可以驗證的對象是一樣的搭配:

Object& a = Object::instance(); 
Object& b = Object::instance(); 

std::cout << &a << std::endl; 
std::cout << &b << std::endl; 

ab應具有相同的內存ADRESS。

這是單身人士的預期行爲:如果多次調用對象構造函數(instance),則會返回相同的實例。

如你所說,instance實際上阻止創建兩個Object。也許你期望你在第二次電話instance上計劃返回一些錯誤。如果你不想這種行爲,你必須使用期待或返回NULL。但是,您編寫的代碼顯示了單例在C++中的經典方式。

+0

非常感謝您的詳細解釋。 – Smii

+0

@Smii沒問題! :) –

2

當我嘗試編譯你的代碼,我從編譯器正確的錯誤:

main.cpp: error: calling a private constructor of class 'Object' Object* ob1= new Object() ;

所以我不能使用new創建兩個對象。

+0

謝謝,但如果我在Ideone上編譯它,它也會成功。見http://ideone.com/1g4ziY – Smii

+0

艾奇。我會向他們提交一份錯誤報告。 – woolstar

+0

是的,我會這樣做的。並嘗試一些不同的C++ 11編譯器。非常感謝! – Smii