簡體   English   中英

在C ++中使用const的正確方法是什么?

[英]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() constchar* 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;

問題的一些變化是返回stringchar * 我認為這與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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM