0

如果我们从函数返回指针,我们可以写

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;
} 
4

4 回答 4

10

似乎不可能返回可以修改 X 的引用,但不能重新分配它?

永远不能重新分配引用。他们一直引用他们在初始化时绑定的同一个引用。

当指针在这方面看起来很有效时,我们为什么要返回引用?

引用的使用更直观,函数的调用者可以像使用变量一样简单地使用引用,这与用户必须处理取消引用等的指针不同。

于 2012-04-13T08:22:14.527 回答
2

重新更新问题:当你做 tmp = tmp2; 在 main 函数中,您没有将 tmp2 的引用分配给 tmp。相反,您正在复制整个对象。

要看到这一点,给 X 复制构造函数打印一些东西。像这样的东西应该工作:

X(X& that)
{
    std::cout << "X is being copied" << std::endl;
    *this = that;
}
于 2012-04-13T08:51:51.473 回答
2

你的前两个例子不一样。你可能是说

const X* f();
X const* f();

实际上,您可以使用引用编写相同的内容:

const X& f();
X const& f();

声明X* const f();没有多大意义。无论如何,您都无法更改返回的指针。这只是一个值。您可以使用该值 (ie f()->foo()) 或存储它 (ie X* copy = f();)。如果您存储该值,则 const-ness 仅取决于您存储该值的变量,而不是值本身。比较int x = 4;-x不会因为4是常数而成为 const。

于 2012-04-13T08:21:37.057 回答
0

似乎不可能返回可以修改 X 的引用,但不能重新分配它?

的确。引用是变量的别名,不能被重新定位(即,更改为另一个变量的别名)。

如果这确实是不可能的,当指针在这个领域看起来很有效时,我们为什么要返回引用呢?

与其说是效力问题,不如说是语义和责任问题。

一个指针:

  • 可能为
  • 可能意味着您需要拥有该对象的所有权(即,它是由创建的new并且必须处置它)

引用没有这些问题,因此更简单。而且简单是好的。因此,当您不需要指针的强大功能时,请省去它的麻烦并使用引用。

于 2012-04-13T08:41:23.387 回答