歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

打破C++ Const 的規則

從一個C++菜鳥改函數開始

1 CString MyClass::GetStringValue() const
2 {
3   return m_strValue;    
4 }

這個值可能還沒有賦值,好吧,那麼我先判斷是不是為空,為空就賦值了

CString MyClass::GetStringValue() const
{
   if(m_strValue.IsEmpty())
      SetStringValue();
  
   return m_strValue;    
}

結果,編譯就不過,因為有個規則:const函數裡面不能調用非const函數。

看到下面的編譯錯誤:

error C2662: “MyClass::SetStringValue”: 不能將“this”指針從“const MyClass”轉換為“MyClass &”

嘿嘿原來是這樣:當我們定義了一個類的成員函數會默認傳進來一個this指針,但是如果是一個const 函數那麼是不是就傳竟來一個const的指針呢?所以我想編譯器看到是這樣的:

CString MyClass::GetStringValue(const MyClass* this)
{
    if(this->m_strValue.IsEmpty())
        this->SetStringValue();

    return this->GetStringValue();
}

後來驗證一下,創建了一個static函數模擬一下:

CString MyClass::GetStringValueS(const MyClass* mcp)
{
    if(mcp->m_strValue.IsEmpty())
        mcp->SetStringValue();

    return mcp->GetStringValue();
}

編譯真的得到一個同樣的錯誤:

error C2662: “MyClass::SetStringValue”: 不能將“this”指針從“const MyClass”轉換為“MyClass &”

所以我試著去打破const規則:

CString MyClass::GetStringValue()const
{
    MyClass * nonconstthis = (MyClass *)this;
    if(m_strValue.IsEmpty())
        nonconstthis->SetStringValue();

    return m_strValue;
}

結果編譯通過,執行也沒有問題。

所以有一個轉換const_cast<>專門來做這樣的事情:

CString MyClass::GetStringValue()const
{
    if(m_strValue.IsEmpty())
        const_cast<MyClass *>(this)->SetStringValue();

    return m_strValue;
} 

最後,我認為,這樣違背了const設計的初衷,這樣對於調用者是一種欺騙(違背契約:我保證不改你),所以不推薦這樣使用。

Copyright © Linux教程網 All Rights Reserved