const T& amp;的区别和T在函数返回

时间:2014-04-10 18:24:04

标签: c++ const return-value

我对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();

这三种情况有什么区别?谢谢。

2 个答案:

答案 0 :(得分:1)

当您通过引用返回一个对象(即T& fun(...) { ...})时,您将返回您在函数内使用的相同对象,而当您按值返回对象时(即T fun(...) { ...})在返回函数之前复制对象。

如果在函数内打印对象的内存地址并在返回后,可以检查这个:

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

const只表示编译器应该确保你没有从外部修改对象(即你不能这样做:object.field = value)。

我已经安排了这个样本,显示了这些方法之间的所有差异:

#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,则使用该引用修改返回的对象是编译时错误。

答案 1 :(得分:1)

T b = a.fun1();

此处,bvector的第0位保留元素的副本。意思是,对前者的任何修改都不会影响后者。

const T& c = a.fun1();

fun1按值返回了一个对象,并且您使用了对const的引用来引用它。考虑到这一点,该对象实际上是“漂浮在太空中”。它的生命周期将与c的生命周期绑定,但仍不是vector原始文件的副本。

const T& d = a.fun2();

fun2const的引用返回到vector内的元素,并将d绑定到该{{1}}。从现在开始,后者是前者的别名。