[英]What's the correct way to use const in C++?
const正確讓我有些困惑。
您使用什么經驗法則來決定什么時候應該是const?
例如,考慮這個例子
class MyClass
{
string ToString(); // this one?
const string& ToString(); // or this?
const string& ToString() const; // or this?
char* ToString(); // What about this?
const char* ToString(); // or this?
const char* ToString() const; // or this?
const char const* ToString(); // Is this legal?
const char const* ToString() const; // how about this?
char const* ToString(); // or even this?
};
Const可能會讓人感到困惑。
所有這些ToString方法之間有什么區別?
如果我理解正確,第一個返回一個新的字符串對象,如果需要可以修改。 第二個返回一個常量引用,也許它應該是字符串const和ToString()。 第三個可能是廢話,因為引用總是不變的是正確的嗎?
以為我會把舊的char *版本放在那里進行比較,因為我有返回對象指針的方法,我不確定它們是否應該是const。
我想我只是想了解const正確性的局限性和好處,以及如何預先確定某些東西是否應該是const以及如何正確地應用const,因為將const放在不同的位置會改變含義。
編輯:另外,我如何處理'...丟棄限定符'。 這究竟意味着什么?
使用const
取決於函數的用途。 正如詹姆斯在他的評論中所建議的那樣(值得作為答案),將const
放在任何地方:
如果該函數旨在修改其對象實例中的狀態, 請不要將const
放在簽名的末尾。
如果該函數旨在修改其中一個引用或指針參數, 請不要在參數上放置const
。
如果通過指針或引用所引用的變量應該被修改, 不要把const
的類型(記住, const
適用於定義之前立即的一部分)。
如果返回的引用/指針引用不應該由接收改變一個變量, 不要把const
的類型。
在不知道功能的目的的情況下,回答問題中給出的例子是不可能的。 我傾向於使用string ToString() const
和char* ToString() const
,以及關於誰負責delete
char*
非常明確的文檔。
另外, const char*
和char const*
是相同的(指向不可修改字符的指針)。 另一方面, char* const
是一個指向可修改字符的不可修改的指針。
我一直用這個常見問題解答來解決這些類型的問題。 http://www.parashift.com/c++-faq-lite/const-correctness.html
您不能重載具有相同名稱和相同參數但返回類型不同的函數。 你可能知道這一點,但只是確定。
()
括號后的const
表示該函數不會更改您調用它的對象。 通常稱為ToString
東西不會改變對象,所以在所有情況下你可能都想要一個const方法。
返回string
和返回const string&
之間的區別在於引用沒有和對象復制並且可能更快,但是只有在已經有string
對象(例如,作為MyClass
的私有成員)時才能執行此操作。 如果不是(比如你需要將幾位數據拼湊在一起,然后返回該字符串),你需要按值返回string
。
使用string
對象通常比使用C樣式的char*
指針更好,但是因為你問:第四個, char*
,會讓其他代碼更改返回字符串中的字符,這可能是一件壞事。 const char*
, char const*
和const char const*
都是一樣的。 char *const
在技術上是不同的,但它不會作為返回類型做太多,因為返回const int
並不重要:調用者可以只復制然后更改返回值。
簡而言之,最好的形式將是:
const string& ToString() const;
string ToString() const;
const char* ToString() const;
問題的一些變化是返回string
與char *
。 我認為這與const
討論無關(如果不是,請告訴我); 我正在考慮string
返回變化。
class MyClass
{
string ToString(); // A
string & ToString(); // B (I added this)
const string& ToString(); // C
const string& ToString() const; // D
};
我的喜好按此順序排列:D,C,B,A。
在所有變體中, const
以兩種方式使用:
返回類型說明符[D中的第一個const
]
這意味着返回的對象不能用於修改返回的對象。 這句話聽起來很有趣,不是嗎? 好吧,可能還有其他修改對象的方法,這個const
無法阻止它。 請參閱此FAQ項目 。
class invariant [D中的第二個const
]
這意味着該方法不會改變(修改)類對象。
我更喜歡D而不是其他任何因為D保證不會修改調用該方法的對象。 如果可以在不修改對象的情況下實現目標(即可以實現方法),那么在設計方面就是一個巨大的勝利。 我盡可能地使用它。 但是如果必須修改對象(即,如果不修改對象就無法實現該方法),則排除D。
其余的B和C都優於A,因為B和C返回一個引用,這避免了A中所需的復制構造。
在B和C之間,C是優選的,因為它返回const
參考。
我發現這是一個有用的指南
您使用什么經驗法則來決定什么時候應該是const?
盡可能地使用它。 然后,當您需要修改對象或授予對可能修改對象的內容的訪問權限(即將引用或代理返回到內部狀態)時, 請不要使用它。
第三個可能是廢話,因為引用總是不變的是正確的嗎?
不,這不正確。 引用是別名,而不是變量。 因此,您無法更改引用“指向”哪個變量,就像使用指針一樣。 但是,您可能引用了一個可變對象( std::string&
)。
所有這些ToString方法之間有什么區別?
它們在內存管理技術方面差異很大,但在高級別,它們都做同樣的事情,除了以下內容:
char* ToString();
那個ont返回一個指向可變數組字符的指針(可能是內部狀態)。
請注意以下系列:
char const* ToString();
const char* ToString(); // or this?
const char const* ToString(); // Is this legal?
寫出同樣的東西都是不同的方式。 無論你是否寫入,本地類型都是按值返回的const。
以下2是C ++中返回字符串的首選方法(在最后提供了一個額外的const
):
string ToString(); // this one?
const string& ToString(); // or this?
您將使用哪兩個取決於您從哪里獲得價值。 如果字符串是數據成員,我建議你選擇后者,因為它通常更快,但如果你的字符串實現使用Copy-On-Write語義則不是很多。 如果必須計算一個值並將其返回,則必須使用前者,因為您無法返回對局部變量的引用。
以下兩個是正確的,但我仍然建議你使用std::string
const char* ToString() const; // or this?
const char const* ToString() const; // how about this?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.