我对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 :(得分: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();
此处,b
在vector
的第0位保留元素的副本。意思是,对前者的任何修改都不会影响后者。
const T& c = a.fun1();
fun1
按值返回了一个对象,并且您使用了对const
的引用来引用它。考虑到这一点,该对象实际上是“漂浮在太空中”。它的生命周期将与c
的生命周期绑定,但仍不是vector
原始文件的副本。
const T& d = a.fun2();
fun2
将const
的引用返回到vector
内的元素,并将d
绑定到该{{1}}。从现在开始,后者是前者的别名。