2016-05-16 65 views
2

我正在實現一個線程安全的單例。但是這方面(單線​​程&線程安全)不是我的問題的一部分。C++單例,奇怪的錯誤

比較兩個代碼。代碼1:

#include <iostream> 
using namespace std; 
class DataLocation { 
private: 
    DataLocation(std::string) { 
    } 
public: 
    DataLocation& getInstance() { 
    std::string s = " "; 
    static DataLocation instance(s); 
    return instance; 
    } 
}; 
int main() { 
} 

和代碼2:

#include <iostream> 
using namespace std; 
class DataLocation { 
private: 
    DataLocation() { 
    } 
public: 
    DataLocation& getInstance() { 
    static DataLocation instance();  
    return instance; 
    } 
}; 
int main() { 
} 

代碼1編譯罰款。代碼2給出了以下錯誤:

15_singleton.cpp: In member function ‘DataLocation& DataLocation::getInstance()’: 
15_singleton.cpp:15:34: error: cannot declare static function inside another function 
    static DataLocation instance();  
           ^
15_singleton.cpp:16:12: error: invalid initialization of non-const reference of type ‘DataLocation&’ from an rvalue of type ‘DataLocation (*)()’ 
    return instance; 
      ^

從我的角度來看唯一的區別是私人構造函數有一個,分別爲零參數。

我該如何幫助編譯器理解我沒有定義任何新東西,但我只是調用構造函數?只有一個參數時,編譯器能夠理解它。

+2

或使用大括號。 – MikeMB

+1

關於您的線程安全部分,請閱讀C++保證初始化時間和靜態順序。 – deviantfan

+0

@MikeMB:你用_大括號_指什麼意思? – LiPo

回答

5

刪除括號,

static DataLocation instance; 

要使用默認的構造函數創建實例。

或者,使用加載形式的初始化。

static DataLocation instance {}; 
+0

@ LiPo這完全是「合乎邏輯的」; MVP是一個明確的語言規則。明確定義的 –

+2

不一定合乎邏輯。一個參數:foo(param),沒有參數foo()。這對我來說是合乎邏輯的。我們都是不同的,我們有不同的邏輯 – LiPo

1

方法getInstance()應該聲明爲靜態。

+0

我也將它定義爲靜態的,但我用這[模型](http://stackoverflow.com/a/19907903),和模型得到+33 ...和我'初學者 – LiPo

+0

@Niall:沒有歧義。一些驚喜?當然。但根據定義,不存在歧義。順便說一句,最令人頭疼的解析涉及'A a(B());'。在使用錯誤的聲明語法之後,它與新手的意外相同的語言規則。 –

+1

@ LiPo:我沒有downvote,但雖然Radek是對的,但它並沒有回答這個問題。 – MikeMB

2
static DataLocation instance = DataLocation(); 

static DataLocation instance; 

而且你可能會想聲明DataLocation& getInstance();static方法。

+4

不知道你爲什麼想要第一個版本。特別是對於單例,通常禁用複製構造函數,因此第一個版本不應該編譯。 – Galik

2

您正在使用括號()同時宣佈

static DataLocation instance(); 

您打算創建一個對象。但是,只是一個函數聲明。並且您不能在其他某些非static函數內創建static函數。這就是你的錯誤所指的。