2011-07-21 124 views
3

我有一個一類是單定義如下C++單例類返回const引用

class myData { 
private: 
    myData (void); // singleton class. 
    // Copy and assignment is prohibted. 
    myData (const myData &); 
    myData & operator=(const myData &); 
    static myData* s_pInstance; 

public: 
    ~myData (void); 
    static const myData & Instance(); 
     static void Terminate(); 

    void myFunc() { cout << "my function..." ;} 
}; 

//在CPP文件。

myData* myData::s_pInstance(NULL); 

myData::myData(){} 

myData::~myData() 
{ 
    s_pInstance = NULL; 
} 

const myData& myData::Instance() 
{ 
    if (s_pInstance == NULL) 
    { 
     s_pInstance = new myData(); 
    } 

    return *(s_pInstance); // want to avoid pointer as user may deallocate it, so i used const referense 
} 

void main() { 

    (myData::Instance()).myFunc(); 

} 

我收到以下錯誤

錯誤C2662: 'myData的:: myFunc的':不能從 '常量myData的' 轉換 '這個' 指針 'myData的&'

如何避免以上問題並從實例函數調用返回const引用的函數?

謝謝!

+0

請參閱:http://stackoverflow.com/questions/1008019/c-singleton-design-pattern/1008289#1008289 –

回答

8

您希望將func()聲明爲常量成員函數,因此編譯器知道它不會違反函數instance()的常量返回值。

您也可以使instance()函數返回一個「常規」參考,與const一樣。

因此,要麼轉: void myFunc()void myFunc() const

或關閉: const myData& myData::Instance()myData& myData::Instance()

4

如果你調用一個const引用的函數,調用該函數也必須是const,你的情況void myFunc() const

否則,您可能會返回一個非const引用,如果更好的話。

3

錯誤說myData::Instance()是類的常量實例,它不能調用該myFunc(),因爲myFunc()可能會改變的情況下,你不能改變一個const實例。

當然,你知道,myFunc()不能真正改變的情況下,但你必須做廣告這個事實,具體如下:

void myFunc()const{ cout << "my function..." ;}

2

避免辛格爾頓是整個討論如果你真的在實施一個單身人士,那麼很有可能擁有所有邪惡的模式或源頭,但是正如你所期望的那樣,常量正確性不會在那裏工作,所以你應該意識到一些陷阱。

首先你的錯誤:你Instance()靜態成員返回一個const引用,這意味着你只能執行不修改對象的操作,即調用成員函數標記爲const,或者如果存在的方式使用公共成員不會修改它們的值。我建議的解決方法是修改Instance()以返回非const引用,而不是像其他人所建議的那樣創建const。


現在對常量正確性的問題進行更長時間的解釋,以適用於您的特定Singleton問題。基本問題是,當你實現一個類型時,你將那些修改對象的成員與那些不成員的成員分開,並且將後者標記爲const成員函數,以便編譯器知道你的承諾(允許你調用該方法在一個常量對象上),並幫助你不要破壞它(如果你嘗試修改方法定義中的狀態,就會抱怨)。標記爲const的方法既可以應用於常量對象,也可以應用於非常量對象,但未標記爲const的方法只能應用於不是const的對象。

回到原始的代碼段,如果實現一個單和的訪問對象是由一個Instance()方法,它返回一個const參考的唯一方法,則基本上限制所有的用戶代碼僅使用const中實現的方法你的界面。這意味着有效地要麼所有的方法都是非變異的,或者它們是無用的(不應該使用const_cast)。這又意味着如果您有任何非常量操作,您想要提供一個返回非const引用的Instance()方法。

您可以考慮實施Instance()的兩個變體,但這不會真的有幫助。重載解析不會幫助用戶代碼確定要使用哪個版本,因此您最終將得到不同的方法:Instance(),ConstInstance()(選擇您的姓名),這意味着它取決於用戶代碼來確定要使用哪一個。小的好處是,在他們的代碼中,訪問者的選擇將有助於記錄他們的預期用途,甚至可能會發現一些錯誤,但是更多的時候他們只會調用非常量版本,因爲它的工作原理是

相關問題