返回子类的const引用

时间:2014-10-09 16:08:07

标签: c++ inheritance const-reference

我所知道的

我知道返回一个临时对象的const引用是可以的! (比如这个例子:)

class A {
public:
  virtual const A& clone () { return (A()); }
  virtual std::string name() const { return ("A"); }
};

Returning temporary object and binding to const reference

但是!

如果我想这样做,它仍然是正确的:

class B : public A {
public:
  virtual const A& clone () { return (B()); }
  virtual std::string name() const { return ("B"); }
};

我认为是的,但在执行时,返回的对象仍被视为A对象(如本例所示:)

的main.cpp

#include <iostream>
#include <string>
int main() {
  B bb;
  A* aa = &bb;

  std::cout << aa->clone().name() << std::endl;
}

输出

valgrind ./a.out
==14106== Use of uninitialised value of size 8
==14106==    at 0x401BF9: main (main.cpp:8)
==14106==  Uninitialised value was created by a stack allocation
==14106==    at 0x401BF2: main (main.cpp:8)
B

这是B .. yay ..但这个警告非常可怕......

修改

感谢你,我知道看到我的错误...但我想知道其他一些事情......

执行此操作时,堆栈中到底发生了什么?

1 个答案:

答案 0 :(得分:12)

将引用绑定到临时文件会延长临时文件的生命周期...除非它没有。 §12.2[class.temporary] / p5,重点补充:

  

引用绑定的临时值或临时值   引用绑定到的子对象的完整对象   在参考文件的生命周期内持续存在,除了:

     
      
  • 构造函数的 ctor-initializer (12.6.2)中与引用成员的临时绑定将持续存在,直到构造函数退出。
  •   
  • 函数调用(5.2.2)中与引用参数的临时绑定一直持续到完整表达式完成为止   包含电话。
  •   
  • 函数返回语句(6.6.3)中返回值临时绑定的生命周期未扩展;暂时的是   在return语句中 full-expression 的末尾被销毁。
  •   
  • new-initializer (5.3.4)中对引用的临时绑定一直持续到包含该表达式的完整表达式完成为止   新初始化
  •   

您链接的问题中的案例(std::string foo(); const std::string & s = foo();)没问题; foo()返回的临时生命周期延长到s生命周期结束。在你的代码中,临时绑定到返回的值,并且根据上面的第三个项目符号点,它的生命周期不会被扩展,并且你的函数会返回一个悬空引用。

通常来说,clone()函数应返回指向堆分配副本的指针。