当使用std::shared_ptr的函数返回堆分配的对象时,是否保证该对象是活动的

Is heap allocated object guaranteed to be alive when it is returned from a function with std::shared_ptr?

本文关键字:对象 是否 活动 分配 返回 std shared 函数 ptr      更新时间:2023-10-16

我正在学习C++。我刚刚了解到std::shared_ptr可以用于管理堆分配的对象,就像引用计数一样。

目前,我的编译器(Xcode/Crang/C++11(显示了我想要的确切行为。打印此结果,

Step0
Step1
CREATED!
Step2
Step3
Step5
DESTROYED!
Step6

使用此代码。

class   Obj1
{
    public:
        Obj1() { printf("CREATED!n"); }
        ~Obj1() { printf("DESTROYED!n"); }
};
std::shared_ptr<Obj1> func1 ()
{
    printf("Step0n");
    {
        printf("Step1n");
        std::shared_ptr<Obj1>   o1(new Obj1());
        printf("Step2n");
        std::shared_ptr<Obj1>   o2  =   o1;
        printf("Step3n");
        return  o2;
    }
    printf("Step4n");
}

int main(int argc, const char * argv[])
{
    {
        std::shared_ptr<Obj1>   o3  =   func1();
        printf("Step5n");
    }
    printf("Step6n");
    return 0;
}

但据我所知,当std::shared_ptr被分配给新变量时,这可以通过C++的复制构造函数优化来实现。(我不确定名称…(如果是的话,Obj1实例在从函数返回时可能不能保证是活动的,因为实际上shared_ptr在调用方被破坏并在语义上重新创建。

当然,所有这些都是新手的假设。请让我知道在这种情况下,对对象生存期的实际预期是什么。

PS。这源于我之前的问题:清理堆分配对象的良好实践或惯例?

要么延长了o2的生存期,要么在销毁之前制作了它的副本。无论哪种方式,至少有一个shared_ptr始终存在,因此代码是安全的。

您误解了优化的工作原理。假设我们有一个小例子:

std::shared_ptr<Foo> func()
{
    std::shared_ptr o2;
    o2.reset( new Foo  );
    return o2;
}
std::shared_ptr<Foo> o1 = func();

编译器通过优化可以做的事情看起来是这样的(不完全是这样,但有助于理解这个想法(:

void func( std::shared_ptr<Foo> &o2 )
{
    o2.reset( new Foo  );
}
std::shared_ptr<Foo> o1;
func( o1 );

所以,从您的角度来看,几乎并没有任何变化,只删除了对象的副本(智能指针(。这不会影响福的一生。