2017-11-25 156 views
2

C++的學生在這裏:如果字段通過引用傳遞,則可以在const方法內修改類字段?

今天,在寫一個類,我發現我能修改不可變場與一個const方法,如果字段是通過引用傳遞:

class Foo { 

public: 
    void func1(int & _n) const { _n = 42; } 
    void func2() { func1(n); } 

private: 
    int n; 
}; 

int main() { 
    Foo foo; 
    foo.func2(); 

    return EXIT_SUCCESS; 
} 

我知道這是可能的,因爲一個const方法,簡單的使用這爲const,但如果我通過了場作爲參考,我可以把它直接訪問而無需通過(我還在學習和也還不是很擅長英文,我可能會說錯了);

所以,我的問題是:

什麼是一個const方法的真正的實用,如果非可變字段可以用一個簡單的「絕招」進行修改?

謝謝!

+0

請勿張貼代碼截圖。郵政編碼。 –

+0

已修改,謝謝 –

回答

1

什麼一個const方法

的真正的實用它可以讓你有編譯器保持類不變。但編譯器不會保護你免於在腳下射擊。在const成員函數內部,編譯器只會阻止通過名稱修改類成員。

如果您通過從外部數據的引用,那麼它就是你的。不會有任何令人費解的代碼發出,驗證您沒有傳遞給成員的引用。

這同樣適用於訪問修飾符。他們只會阻止訪問成員名稱。你可以用很多方式打破封裝,編譯器不會妨礙你。

的語言,有保護你墨菲,而不是馬基雅維利機制。如果您使用「技巧」並且違背語言的範圍,它們將無濟於事。正確的封裝取決於程序員,而不是編譯器。

+0

我正在尋找的答案。謝謝! –

0

在現實世界中,你將不會給出一個內部類成員的公共訪問。當你這樣做時,所有的投注都關閉。

const的方法幫助您實施一類的封裝,但你需要有這種封裝在首位 - 通過標記私有數據的私有性。

+0

對不起,我知道,但問題仍然存在與私人領域,只是調用另一個方法。 –

+0

編譯器將不允許你從常量中調用非const方法 - 試一下。 –

+0

好的,但我仍然不明白:我仍然可以從非const方法調用func(),以便我可以直接傳遞給它私人的n字段...? –

0

只需定義const Foo foo;而不是Foo foo;,編譯器將捕獲該錯誤並將再次成爲您的朋友。

0

,我能修改不可變場

您是能夠修改不可變領域,因爲該領域是不是不可變。試圖聲明nconst,你會看到代碼將不再編譯,並且沒有招(短濫用const_cast和調用未定義行爲)將使編譯了。

在代碼唯一const是一個針對func1,從而關「不可見」 Foo* const this(不可修改的指針修改Foo)中的函數爲Foo const* const this(不可修改的指針不可修改Foo)。

事實證明,這兩個虛const的工作完美的設計,因爲以下兩個嘗試將失敗:

  • this = nullptr; // won't compile
  • this->n = 42; // won't compile

然而,這些都不兩個const s與_n參數有關。 _nthis->n指的是相同的int對象,但只有後者看作const

這導致了一個重要的發現。有一個const引用或指向某個東西並具有引用或指向不可變類型的指針是兩件不同的事情。 int是可變的,所以無論何時您有一個非const引用或指針指向一個,都可以進行修改,而不管程序的其他部分是否將int對象視爲const

什麼是一個const方法的真正的實用,如果非可變字段可以 用一個簡單的「絕招」進行修改?

正如我上面所說的,該字段本身不是不可變的。如果你需要一個「訣竅」來關閉編譯器,那麼你只是推動你的運氣。

相關問題