当从具有std :: shared_ptr的函数返回堆分配对象时,它是否保证是活动的?

时间:2013-02-28 03:52:42

标签: c++ c++11 heap shared-ptr

我正在学习C ++。我刚学会std::shared_ptr可用于管理堆分配的对象,如引用计数方式。

目前我的编译器(Xcode / Clang / 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("Step0\n");
    {
        printf("Step1\n");
        std::shared_ptr<Obj1>   o1(new Obj1());
        printf("Step2\n");
        std::shared_ptr<Obj1>   o2  =   o1;
        printf("Step3\n");
        return  o2;
    }
    printf("Step4\n");
}



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

但据我所知,当std::shared_ptr被分配给新变量时,这可以通过C ++的复制构造函数优化来实现。 (我不确定名称......)如果是,则Obj1实例在从函数返回时可能无法保证活着,因为实际上shared_ptr被销毁并重新在语言上打电话给来电者。

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

PS。这来自我之前的问题: Good practice or convention for cleanup heap allocated object?

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:4)

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

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 );

因此,从您的角度来看,几乎没有任何改变,只删除了对象(智能指针)的副本。它不会影响Foo的生命。