2010-07-09 23 views
16

在C++中,什麼是引用回報的意義?

function() = 10; 

作品如果函數通過引用返回的變量。

它有什麼用途?

+3

儘管如此,沒有必要使用該語法。你總是可以返回一個代理類對象,它的'operator ='在後臺執行任務 – 2010-07-09 10:03:41

+1

這就是爲什麼我從來沒有掌握C++的東西......你永遠都不會停下來發現新的語法,這完全打擊你的思想。得愛操作員重載:| – 2010-07-09 10:05:00

+0

您甚至可以按值返回並分配給臨時。這就是爲什麼斯科特邁爾斯建議按常值返回的原因。 – Philipp 2010-07-09 10:07:59

回答

20

最常見的情況是實現諸如operator []之類的東西。

struct A { 
    int data[10]; 
    int & operator[](int i) { 
     return data[i]; 
    } 
}; 

另一種方法是通過一個accesor函數從一個類返回一個大對象:

struct b { 
    SomeBigThing big; 
    const SomeBigThing & MyBig() const { 
     return big; 
    } 
}; 

以避免複製的開銷。

2

如果你有一個包含另一種結構的類,它可以直接修改包含結構有用:

struct S 
{ 
    int value; 
}; 

class C 
{ 
    public: 

     S& ref() { return m_s; } 

    private: 

     S m_s; 
}; 

讓你寫類似:

void foo() 
{ 
    C c; 

    // Now you can do that: 

    c.ref().value = 1; 
} 

注意:在這個例子中,直接公開m_s而不是返回引用可能更直接。

0

std::vectoroperator[]否則就不允許vec[n] = m

3

一個非常正常的用例是當你像類一樣寫一個數組時。在這裏,你要重載operator []所以你可以做a[0] = 10;在這種情況下,你會想要簽名要像int& operator[](int index);

4

getter/setter方法例如

class C 
{ 
    int some_param_; 
public: 
    int& param() { return some_param_; } 
    int const& param() const { return some_param_; } 
}; 

但在這裏,你應該some_param是一個去public int。容器提供了通過引用返回的函數,例如。 vector<T>::operator[],以便您可以編寫v[k] = x

+0

當您需要刪除或替換另一個類型的對象的some_param_時,此實現很難重構。 – Basilevs 2010-07-09 10:15:16

2

SO搞砸了我的答案

你甚至都不需要返回一個參考:

struct C { }; 

C f() { 
    return C(); 
} 

int main() { 
    C a; 
    f() = a; // compiles fine 
} 

由於這種行爲是相當驚人,你通常應該返回一個常量的值或常量除非用戶有明智的意圖修改結果。

2

實現存取

class Matrix 
{ 
    public: 
     //I skip constructor, destructor etc 

     int & operator()(int row, int col) 
     { 
     return m_arr[row + col * size]; 
     } 

    private: 
     int size; 
     int * m_arr; 
} 

Matrix m(10); 
m(1,0) = 10; //assign a value to row 1, col 0 
+0

我不知道爲什麼,但我討厭矩陣類(我是一個數值分析師) – 2010-07-09 13:24:13

7

時,它可以是有用的考慮下面的代碼,MyFunction的返回一個指針爲int,並且將值設置爲int。

int *i; 
i = MyFunction(); 
*i = 10; 

現在縮短,要

*(MyFunction()) = 10; 

它做同樣的事情作爲第一個代碼塊。

您可以將引用看作只是一個總是取消引用的指針。所以,如果我的函數返回的引用 - 不是指針 - 爲int弗里斯特代碼塊將成爲

int &i; 
i = MyFunction(); 
i = 10; 

和第二將成爲

MyFunction() = 10; 

這就是我一直在尋找

+2

您發佈的代碼不合法​​C++ - 必須初始化引用。 – 2010-07-09 15:19:57

1

另一個經典案例:

class Foo { 
    Foo(); 
public: 
    static Foo& getSingleton(); 
}; 
0

你也可以實現方法鏈接(如果你願意的話)u通過參考唱回來。

class A 
{ 
public: 
    A& method1() 
    { 
     //do something 
     return *this; //return ref to the current object 
    } 
    A& method2(int i); 
    A& method3(float f); //other bodies omitted for brevity 
}; 

int main() 
{ 
    A aObj; 
    aObj.method1().method2(5).method3(0.75); 

    //or use it like this, if you prefer 
    aObj.method1() 
     .method2(5) 
     .method3(0.75); 
} 
0

named parameter idiom是另一種用例。考慮

class Foo 
{ 
public: 
    Foo(
     int lions, 
     float tigers, 
     double bears, 
     std::string zookeeper 
    ); 
}; 

用戶這個類的需要記住每個參數

Foo foo(1, 2.0, 5, "Fred"); 

它可以不看標題不明顯的位置。相比於創造者類,像這樣

class CreateFoo 
{ 
friend class Foo; 
public: 
    CreateFoo(); 

    CreateFoo& lions(int lions) { 
     _lions = lions; 
     return *this; 
    } 

    CreateFoo& tigers(float tigers) { 
     _tigers = tigers; 
     return *this; 
    } 

    CreateFoo& bears(double bears) { 
     _bears = bears; 
     return *this; 
    } 

    CreateFoo& zookeeper(const std::string& zookeeper) { 
     _zookeeper = zookeeper; 
     return *this; 
    } 

private: 
    int _lions; 
    float _tigers; 
    double _bears; 
    std::string _zookeeper; 
}; 

然後可以通過客戶端,像這樣

Foo foo = CreateFoo(). 
    lions(1). 
    tigers(2.0). 
    zookeeper("Fred"). 
    bears(5) 
    ; 

假設Foo有一個構造採取const CreateFoo&使用。