簡體   English   中英

C++ Singleton class 返回常量引用

[英]C++ Singleton class returning const reference

我有一個 class 它是 singleton 定義如下

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”:無法將“this”指針從“const myData”轉換為“myData&”

如何避免上述問題並從返回 const 引用的實例 function 調用 function?

謝謝!

您想將func()聲明為常量成員 function,因此編譯器知道它不會違反instance() function 的常量返回值。

相反,您也可以使instance() function 返回與const相對應的“常規”引用。

所以要么把: void myFunc()變成void myFunc() const

或者將: const myData& myData::Instance()變成myData& myData::Instance()

如果您在 const 引用上調用 function,則您調用的 function 也必須是 const,在您的情況下為void myFunc() const

否則,如果效果更好,您可能會返回非常量引用。

該錯誤表明myData::Instance()是 class 的 const 實例,並且它不能調用myFunc() ,因為myFunc()可能會更改實例,而您不能更改 const 實例。

當然,你知道myFunc()並不能真正改變實例,但你必須宣傳這個事實,如下:

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

避免討論 Singleton 是一種好的模式還是萬惡之源,如果您實際上正在實現 singleton,那么 const 正確性很可能不會像您期望的那樣在那里工作,所以您應該注意一些陷阱.

首先是您的錯誤:您的Instance() static 成員返回一個 const 引用,這意味着您只能執行不修改 object 的操作,即調用標記為const的成員函數,或者使用公共成員(如果以某種方式存在)不修改它們的值。 我建議的解決方案是修改Instance()以返回非常量引用,而不是像其他人建議的那樣使func() const 。


現在,在應用於您的特定 Singleton 問題時,對一般的 const 正確性問題進行更長的解釋。 基本問題是,當您實現一個類型時,您將修改 object 的成員與未修改的成員分開,並將后者標記為const成員函數,以便編譯器知道您的 promise (允許您調用該方法在常量對象上)並幫助您不破壞它(如果您嘗試修改方法定義中的 state 會抱怨)。 標記為const的方法可以應用於常數和非常數 object,但未標記為const的方法只能應用於不是const的 object。

回到原始代碼,如果您實現 singleton 並且訪問 object 的唯一方法是通過返回const引用的Instance()方法,您基本上將所有用戶代碼限制為僅使用在您的界面中實現的const方法. 這意味着實際上要么所有方法都是非變異的,要么它們是無用的(永遠不應該使用const_cast )。 這反過來意味着,如果您有任何非常量操作,您希望提供一個返回非常量引用的Instance()方法。

您可以考慮實現Instance()的兩個變體,但這並沒有真正的幫助。 重載解析無助於用戶代碼確定使用哪個版本,因此您最終將不得不使用不同的方法: Instance()ConstInstance() (選擇您的名稱),這意味着由用戶代碼來確定哪個一個使用。 一個小的優勢是,在他們的代碼中,訪問器的選擇將有助於記錄他們的預期用途,甚至可能會捕獲一些錯誤,但他們通常只會調用非常量版本,因為它可以工作

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM