2014-04-10 52 views
0

我與const T &和T在函數返回中混淆。函數返回中const T&和T之間的差別

例如,我有一個A級:

class A { 
    private: 
    vector<T> my_vector_; 
    public: 
    T fun1() { 
     return my_vector_.at(0); 
    } 
    const T& fun2() { 
     return my_vector_.at(0); 
    } 
} 

然後,

Class A a; 
T b = a.fun1(); 
const T& c = a.fun1(); 
const T& d = a.fun2(); 

什麼是這三種情況區別?謝謝。

+0

稍後您可以在程序中爲'b'分配一個不同的值,但'c'和'd'都是const的引用,所以它們不能被修改。我不確定這是你問的問題,你的問題有點含糊。 –

回答

1
T b = a.fun1(); 

這裏,b持有vector的0位置複製元件的。意思是,對前者進行的任何修改都不會影響後者。

const T& c = a.fun1(); 

fun1通過值返回的對象,而且你已經使用了參考const引用它。考慮到這一點,該物體真的是「漂浮在太空中」。它的使用期限將限於c,但不是來自vector的原件的副本。

const T& d = a.fun2(); 

fun2回到const一個引用元素的vector的內部,你勢必d它。從現在開始,後者是前者的別名。

+0

謝謝faranwath。我對第二種情況有點困惑。在這種情況下,c指向矢量位置0處的元素的副本。所以,如果我刪除了常量限制,它應該和第一種情況幾乎一樣,是嗎?它們在內存分配方面有什麼不同(我認爲它們都在堆棧上,並且生命週期被綁定到外部函數)? – xieziban

+0

*因此,如果我刪除了常量限制,它應該與第一種情況幾乎相同,這是正確的嗎?*不,並且有很好的理由。鑑於對象是暫時的,對它的任何修改都是無用的,因爲通常你無法得到它。例如,如果一個函數'foo'通過引用非''constst''來接收'A',並且像'foo(A {})'一樣調用它,那麼對該函數內部的對象所做的任何改變將會是一旦它返回就會丟失。鑑於參數的類型是'A&',你通常會認爲任何改變都會持續下去。 –

0

當你通過引用返回一個對象(即T& fun(...) { ...}),那麼你是當你返回函數之前的值(即T fun(...) { ...})的對象被複制返回的對象返回您正在使用自己的函數中,而同一個對象。

您可以檢查這個,如果你打印的功能裏面,並已回到住處後,你的對象的內存地址:

printf("%p\n", &my_object); 

const只是說編譯器應該確保你不會從修改對象外(即你不能這樣做:object.field = value)。

我已經安排這樣,顯示所有那些approches之間的差異:

#include <stdio.h> 

class X { 
    public: 
     int i; 

     X(); 
     X(const X&); 
}; 

// Copy constructor 
X::X(const X& x) { 
    printf("Copy constructor invoked\n"); 
} 

// Default constructor 
X::X() : i(0) { 
    printf("Creating a object\n"); 
} 

X my_fun_1(X& x) { return x; } 
X& my_fun_2(X& x) { return x; } 
const X& my_fun_3(X& x) { return x; } 

int main() { 
    X x0; 

    printf("\nInvoke my_fun_1\n"); 
    X x1 = my_fun_1(x0); 

    printf("\nInvoke my_fun_2\n"); 
    X& x2 = my_fun_2(x0); 

    printf("\nInvoke my_fun_3\n"); 
    const X& x3 = my_fun_3(x0); 

    printf("\nResults:\n"); 
    printf("x0 => %p\n", &x0); 
    printf("x1 => %p\n", &x1); 
    printf("x2 => %p\n", &x2); 
    printf("x3 => %p\n", &x3); 

    x0.i = 1; 
    x1.i = 1; 
    x2.i = 1; 
    //Compile-time error: x3.i = 1; 

    return 0; 
} 

編譯並執行它時,輸出應爲:

$ g++ a.cpp && ./a.out 
Creating a object 

Invoke my_fun_1 
Copy constructor invoked 

Invoke my_fun_2 

Invoke my_fun_3 

Results: 
x0 => 0x7fff8710cce0 
x1 => 0x7fff8710ccf0 
x2 => 0x7fff8710cce0 
x3 => 0x7fff8710cce0 

說明:

  • 如果您不使用&則使用複製構造函數
  • 如果使用const,則使用該引用修改返回的對象是編譯時錯誤。
+0

謝謝你的回覆!但是最讓我困惑的是X&x4 = my_fun_1(x0)。 faranwath在上面給出了一個很好的解釋,但是謝謝你們。 – xieziban

相關問題