2009-12-27 139 views
7

我遇到const成員函數的兩個說明約const成員函數

class A{ 
    public: 
    ... 
    void f() const {} 
    ... 
} 
  1. 這意味着它只能訪問恆定成員;
  2. 這意味着它不會修改任何成員;

我認爲第二個是正確的。但爲什麼第一個出來?有什麼要澄清的嗎?

謝謝!

+1

你的C++書是怎麼說的? – 2009-12-27 16:42:11

+6

這個網站**是我的C++書! – 2009-12-27 17:42:14

+0

他們都是正確的。在一定程度上(見下文)。 – 2009-12-27 19:36:15

回答

18

您可以檢查const成員函數中的所有類成員值,在某些情況下甚至可以更改成員變量的值。第一種解釋是不正確的,我不知道它來自哪裏。第二種解釋是正確的,但有一些例外。

這條規則有一些例外。您還可以更改可變的變量在一個const成員函數,例如宣佈這樣一個成員變量:

mutable float my_rank; 

您還可以通過const_cast'ing一個參考給自己這樣的破壞const,正確性類:

Class* self = const_cast<Class*> (this); 

雖然技術上允許使用C++,但這通常被認爲是不好的形式,因爲它會拋棄設計的所有const修飾符。不要這樣做,除非你真的必須這樣做,並且如果你發現自己不得不這麼做,那就意味着你的設計存在問題。 C++ FAQ涵蓋了這一點。

這裏有情況下,兩個引用您希望做更多閱讀:

5

在一個簡單的意思,const函數,你不能改變的狀態物體。

在const函數這個指針表現爲常量指針爲const數據,其中如在非const函數它的行爲就像const的指針數據

void foo() const --> const ClassName * const this (so you can't alter data) 

void foo() --> ClassName * const this (so you can alter data) 

就const數據成員而言,您可以從任何成員函數(無論是否爲const)訪問(讀取)它。

正如詹姆斯·湯普森已經表明,你甚至可以用,如果你想這樣的去除常量性改變對象的狀態。

class Bar 
{ 
    int bar; 
    public: 
    void foo() const 
    { 
     this->bar = 0; //flashes error 

     Bar * const thisClass = const_cast<Bar * const>(this); 
     thisClass->bar = 0; 
    } 
}; 

也可以在const函數中更改可變數據成員。

1

我認爲當你有A型const對象在這種情況下,你只能調用聲明爲如F()在這種情況下const的成員函數作一些澄清後的情況下,1可能涉及的情況。所以根據你的帖子,你必須假定'它'是類型爲const A的對象上的成員函數的調用者。也許你應該回顧一下你發現的定義時要考慮到這個假設。

2

它們都是正確的。

一個const成員函數不能改變該對象的狀態

  • 這意味着它可以讀取(但不能修改)所有成員變量。
  • 這也意味着它只能調用其他的const成員函數
    保證不改變對象狀態的其他方法。

詹姆斯以上還提到可變成員。
所以我也應該在這裏介紹。

可變成員變量是一個變量,它不是對象狀態的一部分(編譯器不認爲它是對象狀態的一部分)。你也應該這樣對待它。任何成員變量,包含關於對象的狀態信息應該NOT被標記爲可變。您應該只使用它來保存可以從對象狀態重新構建的臨時信息。

一個簡單的例子是日期 - 時間對象。對象具有將數據/時間轉換爲可讀的字符串格式的方法。這個字符串可以緩存在可變成員的對象中以提高效率(這樣就不需要重複構建字符串)。但字符串不是對象狀態的一部分(因爲它可以從其他成員構建)。

另外詹姆斯提到上面使用const_cast拋棄了常量。

除非在非常特殊的情況下,你知道對象永遠不可能是 const這樣做通常被認爲是一個壞主意。因爲它直接導致未定義的行爲。如果你發現自己需要拋棄常量,那麼在你的程序中就會發生設計中的錯誤。

事實上,我只能想到它正常發生的情況。然後,我不願意在沒有首先去研究的情況下將其提交給代碼,以確保我看起來不傻。

+0

我認爲你讀第一個問題比我不同。提出的定義是「它只能訪問常量成員」。一個const成員函數可以訪問非常量成員,只要它不改變它們的狀態,所以定義是不正確的。 – 2009-12-28 01:49:41

+0

@詹姆斯。請讓你的陳述更清楚。一個const方法可以讀取任何成員變量。但是隻能調用const成員方法。我認爲很明顯,原來的問題剛剛有一些細節混雜在一起。 – 2009-12-28 04:19:52

+0

不用擔心,雖然有2個具體的例子。將拿出所有的意見,並開始支持媒體渠道展示瑣碎的觀察。誰知道,也許我會開始看到每輛車的專用車道,而不是一條單一的道路。 – 2009-12-29 11:34:50