C++核心準(zhǔn)則Con.2:默認(rèn)情況下,將成員函數(shù)定義為const類型

秋英
Con.2: By default, make member functions?const
Con.2:默認(rèn)情況下,將成員函數(shù)定義為const類型
Reason(原因)
A member function should be marked?const?unless it changes the object's observable state. This gives a more precise statement of design intent, better readability, more errors caught by the compiler, and sometimes more optimization opportunities.
只要沒有修改對(duì)象的可觀察狀態(tài),就應(yīng)該將成員函數(shù)定義為const類型。這是設(shè)計(jì)意圖的更清晰表達(dá),可以帶來更好的可讀性,方便編譯器捕捉更多的錯(cuò)誤,而且有時(shí)還會(huì)帶來更多的優(yōu)化機(jī)會(huì)。
Example, bad(反面示例)
class Point {
int x, y;
public:
int getx() { return x; } // BAD, should be const as it doesn't modify the object's state
// ...
};
void f(const Point& pt)
{
int x = pt.getx(); // ERROR, doesn't compile because getx was not marked const
}Note(注意)
It is not inherently bad to pass a pointer or reference to non-const, but that should be done only when the called function is supposed to modify the object. A reader of code must assume that a function that takes a "plain"?T*?or?T&?will modify the object referred to. If it doesn't now, it might do so later without forcing recompilation.
傳遞指針或者引用給非常量也不是說一定不好,但是它只應(yīng)該發(fā)生在調(diào)用一個(gè)假定會(huì)修改對(duì)象值的情況下。代碼的讀者必須假設(shè)接受原始T*或T&參數(shù)的函數(shù)會(huì)修改(指針或引用,譯者注)參照的對(duì)象。如果(修改,譯者注)沒有發(fā)生在現(xiàn)在,那么可能是以后會(huì)發(fā)生而且不需要重新編譯。
Note(注意)
There are code/libraries that offer functions that declare a T*?even though those function do not modify that?T. This is a problem for people modernizing code. You can
有些代碼/庫(kù)提供的函數(shù)定義了T*參數(shù)卻沒有修改T。這對(duì)于更新代碼使其適用現(xiàn)在C/C++的人來說是一個(gè)問題,你可以
update the library to be?const-correct; preferred long-term solution
將庫(kù)更新到正確定義const屬性的版本;優(yōu)先使用長(zhǎng)期的解決方案。
"cast away?const";?best avoided
使用常數(shù)類型轉(zhuǎn)換;最好避免這種做法。
provide a wrapper function
提供一個(gè)包裝函數(shù)
Example(示例):
void f(int* p); // old code: f() does not modify `*p`
void f(const int* p) { f(const_cast(p)); } // wrapper
Note that this wrapper solution is a patch that should be used only when the declaration of?f()?cannot be modified, e.g. because it is in a library that you cannot modify.
注意包裝方式是一種只能在f()的聲明無法改變的情況下使用的“補(bǔ)丁”方案。例如當(dāng)函數(shù)使庫(kù)的一部分而無法修改時(shí)。
Note(注意)
A?const?member function can modify the value of an object that is?mutable?or accessed through a pointer member. A common use is to maintain a cache rather than repeatedly do a complicated computation. For example, here is a?Date?that caches (memoizes) its string representation to simplify repeated uses:
const類型的成員函數(shù)可以通過mutable對(duì)象或者借助指針成員修改對(duì)象的值。一個(gè)通常的用法是維護(hù)一個(gè)緩存以回避重復(fù)的計(jì)算。例如,下面的代碼中的Data類就為簡(jiǎn)單的重復(fù)使用緩存(記憶)了一個(gè)字符串表現(xiàn)。
class Date {
public:
// ...
const string& string_ref() const
{
if (string_val == "") compute_string_rep();
return string_val;
}
// ...
private:
void compute_string_rep() const; // compute string representation and place it in string_val
mutable string string_val;
// ...
};
Another way of saying this is that?constness is not transitive. It is possible for a?const?member function to change the value of?mutable?members and the value of objects accessed through non-const?pointers. It is the job of the class to ensure such mutation is done only when it makes sense according to the semantics (invariants) it offers to its users.
說明這件事的另一個(gè)方式是常量屬性是不可傳遞的。一個(gè)const成員函數(shù)修改mutable成員的值,或者通過一個(gè)非const指針訪問對(duì)象值都是可能的。保證這種修改只有在符合其向用戶提供的語(yǔ)義(不變量)是這個(gè)類的工作。
See also:?Pimpl
參見:I.27 考慮使用指向?qū)崿F(xiàn)的指針技術(shù)獲得穩(wěn)定的ABI
Enforcement(實(shí)施建議)
Flag a member function that is not marked?const, but that does not perform a non-const?operation on any member variable.
如果一個(gè)函數(shù)沒有定義為const類型,有沒有執(zhí)行針對(duì)任何成員變量的非常量操作,標(biāo)記它。
原文鏈接
https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#con2-by-default-make-member-functions-const
新書介紹
《實(shí)戰(zhàn)Python設(shè)計(jì)模式》一書是作者最近出版的新書,拜托多多關(guān)注!

本書利用Python 的標(biāo)準(zhǔn)GUI 工具包tkinter,通過可執(zhí)行的示例對(duì)23 個(gè)設(shè)計(jì)模式逐個(gè)進(jìn)行說明。這樣一方面可以使讀者了解真實(shí)的軟件開發(fā)工作中每個(gè)設(shè)計(jì)模式的運(yùn)用場(chǎng)景和想要解決的問題;另一方面通過對(duì)這些問題的解決過程進(jìn)行說明,讓讀者明白在編寫代碼時(shí)如何判斷使用設(shè)計(jì)模式的利弊,并合理運(yùn)用設(shè)計(jì)模式。
對(duì)設(shè)計(jì)模式感興趣而且希望隨學(xué)隨用的讀者通過本書可以快速跨越從理解到運(yùn)用的門檻;希望學(xué)習(xí)Python GUI 編程的讀者可以將本書中的示例作為設(shè)計(jì)和開發(fā)的參考;使用Python 語(yǔ)言進(jìn)行圖像分析、數(shù)據(jù)處理工作的讀者可以直接以本書中的示例為基礎(chǔ),迅速構(gòu)建自己的系統(tǒng)架構(gòu)。
覺得本文有幫助?請(qǐng)分享給更多人。
關(guān)注微信公眾號(hào)【面向?qū)ο笏伎肌枯p松學(xué)習(xí)每一天!
面向?qū)ο箝_發(fā),面向?qū)ο笏伎迹?/span>
