【问题标题】:Returning a reference to an object constructor返回对对象构造函数的引用
【发布时间】:2011-12-29 16:16:29
【问题描述】:

看看这段代码:

Foo &Bar::Copy()
{
    return Bar();
}

类Bar继承自Foo,Foo是一个抽象类。但是当我打电话给Bar() 并返回它时,这样做安全吗?或者我会返回将在 Copy() 函数结束时释放的局部变量的地址?

非常感谢您的建议!

【问题讨论】:

  • @GWW - 不,不是。我不知道返回构造函数是否算作返回本地分配。这可能对其他对同一件事感到困惑的人有益。
  • 实际上这甚至不应该编译,因为右值绑定到非常量引用。

标签: c++ oop constructor reference scope


【解决方案1】:

这是一个未定义的行为,因为临时的 Bar 对象将在 ; 处被销毁。

Foo Bar::Copy()
{
    return Bar();
}

更安全。但是感谢@Cat Plus Plus 和@celtschk,我意识到这种方法会导致切片,丢失所有Bar 特定信息。为了保留Bar 对象Copy() 必须返回一个引用或指向该对象的指针。在这里,我们再次开始,因为这是 UB。所以Bar必须被动态分配,它的引用/指针位于Copy()函数的外面。谁应该负责删除这个动态生成的Bar 对象?

#include <memory>
std::shared_ptr<Foo> Bar::Copy()
{
    return std::shared_ptr(new Bar());
}

shared_ptr 会自动为您执行此操作。

【讨论】:

  • 第二个 sn-p 切片对象。
  • 第一个 sn-p 也对对象进行切片。
【解决方案2】:

你没有返回一个演员。 Bar(); 调用 ctor,创建一个临时对象。然后,您将返回对该临时对象的引用。

由于 C++ 中的 ctor 没有名称,因此您无法在普通函数上执行许多通常的操作,例如获取/返回指向函数的指针。尚不清楚您在这里真正想要完成什么,但是如果您想返回将构造一个对象的东西,您通常需要定义一个调用 ctor 的静态成员函数,并返回一个指向该静态成员函数的指针.

【讨论】:

  • 从长远来看,我正在尝试创建一个Foo* 指针数组(理论上,在我的实际程序中它不称为 Foo )。我担心插入其中的指针的生命周期会使其容易出现未定义的行为,因此我试图插入副本,以便地址的生命周期与数组保持一致。正如 jszpilewski 所提到的,我想使用智能指针并在堆上分配是最好的。
  • @AutoBotAM:你可能还想看看 Boost ptr_vector
  • 指针容器库看起来像我需要的。会试试的。
【解决方案3】:

当调用Bar(); 时,您调用了一个隐式临时对象的构造函数,该对象返回引用。如果您打算创建类似Clone() 的函数,典型的解决方案是使用new 在堆上创建克隆。您可以使用一种智能指针来简化生命周期管理。您还可以应用协变返回类型以避免在某些情况下使用签名进行类型转换:Bar &amp;Bar::Copy()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-30
    • 2013-07-05
    • 2012-08-09
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多