[英]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.