如果我们从函数返回指针,我们可以写
const X* f();
或
X* const f();
,以这种方式控制是否可以重新分配指针或者是否可以在内部修改类。但是当返回引用时,这两个似乎具有相同的含义:
const X& f();
X& const f();
似乎无法返回可以修改X的引用,但不能重新分配它?如果它确实不可能,为什么我们应该在指针在这个区域看起来有效时返回引用?
更新:正如所指出的,无法重新分配引用。然而,这让我更加困惑,因为下面的代码打印33 55,而不是33 33,正如我所料。如何匹配那些引用无法重新分配?
struct X
{
X(int i_) { i = i_;}
int i;
};
struct Y
{
X& get2() {tmp2 = new X(55); return *tmp2;}
X& get() {tmp = new X(33); return *tmp;}
void print () {cout << tmp->i << endl;}
X* tmp;
X* tmp2;
};
int _tmain(int argc, _TCHAR* argv[])
{
Y y;
X& tmp2 = y.get2();
X& tmp = y.get();
y.print();
tmp = tmp2;
y.print();
return 0;
}
答案 0 :(得分:10)
似乎无法返回您可以修改X的引用,但不能重新分配它?
永远不能重新分配参考文献。他们一直在引用他们在初始化时绑定的相同指示物。
为什么我们应该在指针在这个区域看起来有效时返回引用?
参考用法更直观,函数调用者可以像引用一样使用引用,而不像用户必须处理解除引用等的指针。
答案 1 :(得分:2)
你的前两个例子不一样。你可能意味着
const X* f();
X const* f();
你实际上可以用引用写出相同的内容:
const X& f();
X const& f();
声明X* const f();
没有多大意义。无论如何都无法更改返回的指针。这只是一个价值。您可以使用该值(即f()->foo()
)或将其存储(即X* copy = f();
)。如果存储该值,则const-ness仅取决于存储值的变量,而不取决于值本身。比较int x = 4;
- x
不会因为4
是常量而变为常量。
答案 2 :(得分:2)
重新提出更新问题:当你这样做时 tmp = tmp2; 在main函数中,您没有将对tmp2的引用赋给tmp。相反,您正在复制整个对象。
要看到这一点,请给出打印内容的X拷贝构造函数。这样的事情应该有效:
X(X& that)
{
std::cout << "X is being copied" << std::endl;
*this = that;
}
答案 3 :(得分:0)
似乎无法返回可以修改X的引用,但不能重新分配它?
事实上。引用是变量的别名,不能重新设置(即,将其更改为别名另一个变量)。
如果确实不可能的话,为什么我们应该在指针在这个区域看起来有效时返回引用?
这不仅仅是效力问题,更重要的是语义和责任。
指针:
new
创建,您必须处置它)参考没有这些问题,因此更简单。并且简单是好的。因此,当你不需要指针的强大功能时,不要让自己陷入困境并使用引用。