c – 返回子类的const引用

我知道的

我知道返回一个临时对象的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 ..但这个警告非常可怕……

编辑

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

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

解决方法

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

The temporary to which the reference is bound or the temporary that is
the complete object of a subobject to which the reference is bound
persists for the lifetime of the reference except:

  • A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits.
  • A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression
    containing the call.
  • The lifetime of a temporary bound to the returned value in a function return statement (6.6.3) is not extended; the temporary is
    destroyed at the end of the full-expression in the return statement.
  • A temporary bound to a reference in a new-initializer (5.3.4) persists until the completion of the full-expression containing the
    new-initializer.

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

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

相关文章

/** C+⬑ * 默认成员函数 原来C++类中,有6个默认成员函数: 构造函数 析构函数 拷贝...
#pragma once // 1. 设计一个不能被拷贝的类/* 解析:拷贝只会放生在两个场景中:拷贝构造函数以及赋值运...
C类型转换 C语言:显式和隐式类型转换 隐式类型转化:编译器在编译阶段自动进行,能转就转,不能转就编译...
//异常的概念/*抛出异常后必须要捕获,否则终止程序(到最外层后会交给main管理,main的行为就是终止) try...
#pragma once /*Smart pointer 智能指针;灵巧指针 智能指针三大件//1.RAII//2.像指针一样使用//3.拷贝问...
目录&lt;future&gt;future模板类成员函数:promise类promise的使用例程:packaged_task模板类例程...