返回子类的const引用

Col*_*oTV 6 c++ inheritance const-reference

我知道的

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

class A {
public:
  virtual const A& clone () { return (A()); }
  virtual std::string name() const { return ("A"); }
};
Run Code Online (Sandbox Code Playgroud)

返回临时对象并绑定到const引用

但!

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

class B : public A {
public:
  virtual const A& clone () { return (B()); }
  virtual std::string name() const { return ("B"); }
};
Run Code Online (Sandbox Code Playgroud)

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

main.cpp中

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

  std::cout << aa->clone().name() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

产量

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
Run Code Online (Sandbox Code Playgroud)

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

编辑

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

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

T.C*_*.C. 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)中对引用的临时绑定将持续到包含new-initializer的full-expression完成为止 .

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

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