簡體   English   中英

C ++返回值,引用,const引用

[英]C++ Return value, reference, const reference

你能解釋一下返回值,引用值和const引用值之間的區別嗎?

值:

Vector2D operator += (const Vector2D& vector)
{
    this->x += vector.x;
    this->y += vector.y;
    return *this;
}

非const引用:

Vector2D& operator += (const Vector2D& vector)
{
    this->x += vector.x;
    this->y += vector.y;
    return *this;
}

Const參考:

const Vector2D& operator += (const Vector2D& vector)
{
    this->x += vector.x;
    this->y += vector.y;
    return *this;
}

這有什么好處? 我理解const引用傳遞給函數背后的意義,因為你要確保不要修改引用指向函數內部的這個值。 但我對返回const引用的含義感到困惑。 為什么返回引用比返回值更好,為什么返回const引用要比返回非const引用更好?

除非你寫一些奇怪的東西,否則沒有區別

(v1 += v2) = v3;

在第一種情況下,賦值將是臨時的,整體效果將是v1 += v2

在第二種情況下,賦值將是v1 ,因此整體效果將是v1 = v3

在第三種情況下,不允許轉讓。 這可能是最好的選擇,因為這種怪異幾乎肯定是一個錯誤。

為什么返回引用比返回值更好?

它可能更有效:您不必復制該對象。

為什么返回const引用比返回非const引用更好?

你可以像上面的例子一樣防止怪異,同時仍然允許更少的奇怪鏈接

v1 = (v2 += v3);

但是,如評論中所述,這意味着您的類型不支持與內置類型相同的(ab)使用形式,這是某些人認為合適的。

值:

按值返回意味着您將返回對象的副本。 這就要求對類(它必須是可復制的或可移動的)的要求。 這意味着對於按值返回的某些類的對象可能是昂貴的(在RVO或NRVO不起作用或關閉的情況下)。 這也意味着新對象與其他對象是獨立的(取決於其設計),並且是它自己的值。 這可能是你應該從許多二元運算符返回的,如+, - ,*等。

非const引用:

你真的為另一個對象返回別名。 別名為非const允許您修改別名對象。 這是你應該從一些一元的操作符返回的內容,比如前綴++和 - ,以及*(取消引用),因為你通常希望能夠修改返回的對象。

這由運算符>>和運算符<<為流重載而返回。 這允許運營商鏈接:

cout << 5 << "is greater then" << 1 << endl;
cin >> myInt >> myFloat;

當你想允許鏈接這樣的常規方法時,你也可以返回* this的引用:

object.run().printLastRunStatistics();

Const參考:

像上面一樣但你不能修改別名對象。 當要返回的對象復制起來很昂貴,並且在從函數返回后可以確保它存在時,可以使用而不是按值返回。

這就是operator =通常以標准類型支持它們的方式返回以允許多個賦值:

a = b = c;

operator =中使用的const-reference阻止了這種用法(據我記憶,標准類型不支持):

++(a = b);

如果使用正常參考,則允許使用。

它與向函數傳遞參數完全相同。

當您返回對象的屬性時,您希望返回一個const引用,您希望不要在其外部修改它。 例如:當您的對象具有名稱時,您可以使用以下方法const std::string& get_name(){ return name; }; const std::string& get_name(){ return name; }; 哪種方式最佳。 您允許對內部屬性進行“只讀”訪問,而不進行復制。

當您重載運算符時,您應該返回一個可變的對象,否則通常預期會運行的某些語法會產生錯誤。 當你嘗試一些奇怪的鏈接時,這是非常重要的。

例如,選項3不適用於(v1 += v2).non_const_method() ,而以下將:

v1+=v2;
v1.non_const_method();

返回值返回引用之間的差異在運行時生效:

返回對象的值時,將調用copy-constructor,並在堆棧上創建臨時實例。

當您按引用返回對象時,上述所有操作都不會發生,從而提高了性能。


返回引用返回常量引用之間的區別沒有運行時效果,只是為了保護您不會編寫錯誤的代碼。

例如,使用Vector2D& operator += (const Vector2D& vector) ,您可以執行以下操作:

(x+=y)++(x+=y).func()其中funcVector2D類中的非const函數。

但是使用const Vector2D& operator += (const Vector2D& vector) ,編譯器將為任何此類類似嘗試生成錯誤。

正如指出但luk32只是為了確保不允許對此函數返回的對象進行任何更改。 這基本上可以幫助您在編譯時找到邏輯錯誤。 假設您確定不更改對象,並且您的代碼正在更改對象,則可以對其進行跟蹤。 可以認為它是一種很好的編碼實踐。

暫無
暫無

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

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