Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
当使用std::shared\u ptr从函数返回堆分配的对象时,是否保证该对象处于活动状态? 我正在学习C++。我刚刚了解到,std::shared_ptr可以用引用计数的方式来管理堆分配的对象_C++_C++11_Heap_Shared Ptr - Fatal编程技术网

当使用std::shared\u ptr从函数返回堆分配的对象时,是否保证该对象处于活动状态? 我正在学习C++。我刚刚了解到,std::shared_ptr可以用引用计数的方式来管理堆分配的对象

当使用std::shared\u ptr从函数返回堆分配的对象时,是否保证该对象处于活动状态? 我正在学习C++。我刚刚了解到,std::shared_ptr可以用引用计数的方式来管理堆分配的对象,c++,c++11,heap,shared-ptr,C++,C++11,Heap,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&g

目前,我的编译器(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;
}
Obj1类
{
公众:
Obj1(){printf(“已创建!\n”);}
~Obj1(){printf(“已销毁!\n”);}
};
std::共享的函数1()
{
printf(“步骤0\n”);
{
printf(“步骤1\n”);
std::shared_ptr o1(新的Obj1());
printf(“步骤2\n”);
std::共享_ptr o2=o1;
printf(“步骤3\n”);
返回氧气;
}
printf(“步骤4\n”);
}
int main(int argc,const char*argv[]
{
{
std::shared_ptr o3=func1();
printf(“步骤5\n”);
}
printf(“步骤6\n”);
返回0;
}
但据我所知,当
std::shared_ptr
被分配给新变量时,这可以通过C++的复制构造函数优化实现。(我不确定名称…)如果是,则当从函数返回时,
Obj1
实例可能不能保证是活动的,因为实际上,
shared_ptr
在调用方的语义上被销毁和重新引用

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

注:这是从我前面的问题中得出的:

要么延长o2的寿命,要么在销毁之前复制一份。无论如何,至少有一个
共享\u ptr
始终存在,因此代码是安全的。

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

std::shared_ptr<Foo> func()
{
    std::shared_ptr o2;
    o2.reset( new Foo  );
    return o2;
}
std::shared_ptr<Foo> o1 = func();
std::shared_ptr func()
{
std::共享的ptr o2;
o2.重置(新的Foo);
返回氧气;
}
std::shared_ptr o1=func();
编译器通过优化所能做的事情如下(不完全是这样,但有助于理解这个想法):

void func(std::shared_ptr&o2)
{
o2.重置(新的Foo);
}
std::共享的ptr o1;
func(o1);

所以,从您的角度来看,几乎没有任何变化,只有对象的副本(智能指针)被消除。它不会影响Foo的生存期。

“…当std::shared_ptr分配给新变量时,C++的复制构造函数优化可能会发生这种情况。”-您的意思是当
func1()
中的
o2
复制到
main()
中的
o3
时?“(我不确定名称…)-你是指R eturn-V值优化吗?@MarkGarcia目前我认为,
o3
是通过复制
o2
新创建的。我不确定引用计数是否可以在函数边界处降至
0
。这就是问题所在…@MarkGarcia,我想那是RVO。我想不出这个名字。谢谢。如果你害怕这种语言,它将无法使用。如果RVO不发生,那么函数的对象在另一个拷贝之后被破坏,所以<代码> Obj被新的CopyCon保持活力。我确信这是由C++语义保证的,不是由优化的副作用所造成的。@ EONIL标准是由优秀的人形成的(尽管他们太喜欢不明确的行为)。. 他们已经仔细检查了(几乎)这些东西的所有可能的使用场景。放心。你在安全的人手里。@Eonil:这两件事中的一件肯定会发生,而且两件都是安全的。
void func( std::shared_ptr<Foo> &o2 )
{
    o2.reset( new Foo  );
}
std::shared_ptr<Foo> o1;
func( o1 );