簡體   English   中英

C++ getter 應該返回什么

[英]What should a C++ getter return

C++ getter 方法的最佳實踐是什么,它應該返回一個非平凡的類型,但是一個類型為 class 或 struct 的成員。

  1. 按值返回,如: MyType MyClass::getMyType() { return mMyType; } MyType MyClass::getMyType() { return mMyType; }
  2. 通過 const 引用返回: const MyType& MyClass::getMyType() { return mMyType; } const MyType& MyClass::getMyType() { return mMyType; }
  3. 按地址返回: MyType* MyClass::getMyType() { return &mMyType; } MyType* MyClass::getMyType() { return &mMyType; }

在哪里

class MyType { /* ... */ };

class MyClass
{
  private:
     MyType mMyType;
}

我特別擔心這種方法的以下用法。 您能否詳細說明這可能會如何影響復制對象,以及如果function()想要保存它以供進一步使用時懸空引用和野生指針的危險。

MyType* savedPointer;

SomeType function(MyType* pointer) { savedPointer = pointer; };

一種。 對 1. 和 2. 有效。

{
  MyType t = myClass.getMyType();
  function(&t);
}

// is savedPointer still valid here?

對 1. 和 2. 有效。

{
  const MyType& t = myClass.getMyType();
  function(&t);
}

// is savedPointer still valid here?

C。 對 1. 和 2. 有效。

{
  MyType& t = myClass.getMyType();
  function(&t);
}

// is savedPointer still valid here?

d. 有效期為 3。

{
  MyType* t = myClass.getMyType();
  function(t);
}

// is savedPointer still valid here?

其中myClassMyClass類型的對象。

您可以提供常量和非常量版本:

MyType       & MyClass::getMyType()       { return mMyType; }
MyType const & MyClass::getMyType() const { return mMyType; }

我不會提供指針版本,因為這意味着返回值可能是空指針,在這個實例中它永遠不會是空指針。

然而,真正的重點是您基本上是讓調用者直接訪問內部對象。 如果這是您的意圖,那么您不妨將數據成員設為公開。 如果不是,那么您將需要更加努力地隱藏對象。

一種選擇是保留MyType const &訪問器,但提供更間接的方法來修改內部對象( setMyType(…)或更適合您試圖在包含類級別表達的語義的東西)。

通常,您應該更喜歡按值返回,除非您明確希望保證引用將指定一個成員(它公開了您的實現的一部分,但在std::vector<>::operator[]類的情況下是可取的)。 返回引用可防止類中的后續更改,因為這意味着您無法返回計算值。 (如果類被設計為基類,這一點尤其重要,因為返回引用會為所有派生類創建此限制。)

您應該通過指針返回的唯一時間是如果涉及查找或某些事情,這可能會返回必須返回空指針。

返回對 const 的引用可能是一個有效的優化,如果分析器在這里指出性能問題,並且調用站點也可以處理一個 const 引用(不修改返回值,對象生命周期沒有問題)。 當然,它必須與實施上的額外約束進行權衡,但在某些情況下,這是合理的。

我總是會返回一個常量引用。 如果您需要修改它返回的值,只需使用 setter 函數。

按值返回,如: MyType MyClass::getMyType() { return mMyType; } MyType MyClass::getMyType() { return mMyType; }應該避免,因為你會復制你的對象的內容。 我沒有看到您可以獲得的收益,但我看到了性能上的缺點。

通過 const 引用返回: const MyType& MyClass::getMyType() { return mMyType; } const MyType& MyClass::getMyType() { return mMyType; }更generaly這樣使用:

const MyType& MyClass::getMyType() const { return mMyType; }
MyType& MyClass::getMyType() { return mMyType; }

始終提供 const 版本。 非常量版本是可選的,因為這意味着有人可以修改您的數據。 這是我鼓勵你使用的。

按地址返回: MyType* MyClass::getMyType() { return &mMyType; } MyType* MyClass::getMyType() { return &mMyType; }主要用於數據可選的情況。 通常在使用前必須進行檢查。

現在,您的用例,我強烈建議不要將指針保存在超過一個范圍內。 我經常會導致所有權問題。 我你必須這樣做,看看shared_ptr

對於您的示例,有兩種情況:

一種。 在結束大括號之后,savedPointer 將不再有效。

b、c 和 d。 savedPointer 在右大括號之后有效,但請注意它不應超過myClass

a) MyType t =將為 1 和 2 創建對象的副本。一旦 t 超出范圍,保存的指針將無效。

b) 保存的指針對返回引用的情況有效,但對返回對象的情況無效。 對於引用,指針的生命周期與 myClass 相同。 當然, const ref 上的 &t 將是 const t* 而不是 at* ,因此無法在您對function(MyType*)調用中進行轉換。

c) 與 b 相同,但代碼對 2 無效,因為您不能將const MyType&轉換為MyType& 通常這將是不好的做法,const 形式會更容易接受。

d) savedPointer 將與 myClass 具有相同的生命周期。

我通常傾向於返回引用或常量引用,具體取決於您期望能夠對返回值做什么。 如果您返回一個引用(非常量),您可以執行以下操作: myClass.getMyType() = ... ,而如果您返回一個 const 引用,則該對象是只讀的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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