我正在学习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?
答案 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的生命。