共享指针和原始指针生存期

时间:2017-01-27 01:15:22

标签: c++ pointers smart-pointers lifetime temporaries

有人可以解释为什么这不起作用的原因:

std::shared_pointer<Bar> getSharedPointer() {
    return std::make_shared<Bar>();
}

...

auto foo = getSharedPointer().get();

显然使用原始指针foo会导致段错误,因为getSharedPointer()返回的共享指针的生命周期将耗尽。不知怎的,我希望它能持续到它的范围结束(就像它里面的任何一块)。

这是正确的吗?这种情况有没有类似的例子?

2 个答案:

答案 0 :(得分:7)

对于getSharedPointer().get();getSharedPointer()返回一个临时的std::shared_ptr,它将在表达式后立即销毁,并且由它管理的指针也将被删除。在那之后foo将被悬空,任何取消引用它都会导致UB。

auto foo = getSharedPointer().get();
// foo have become dangled from here

您可以使用命名变量:

auto spb = getSharedPointer();
auto foo = spb.get();
// It's fine to use foo now, but still need to note its lifetime
// because spb will be destroyed when get out of its scope
// and the pointer being managed will be deleted too

答案 1 :(得分:1)

auto foo = getSharedPointer().get();

每当一个函数返回一个不是引用的类型时,调用该函数的结果就是一个rvalue。此外,因为函数getSharedPointer()返回类类型,结果是临时对象。

该临时对象的生命周期定义为最外层表达式的评估结束,此处为getSharedPointer().get()。一旦初始化foo变量,就会销毁拥有的智能指针;当拥有该对象的最后一个shared_ptr被删除时,该对象将被删除。

此处getSharedPointer()始终返回不会共享托管对象的shared_ptruse_count()为1),因此当最后一个shared_ptr的副本被销毁时,对象被破坏,指向对象的指针无效。

(我不确定您为什么要在这里退回shared_ptr而不是unique_ptr。)

正确使用智能指针,或任何&#34;拥有&#34; (控制其生命周期)其他资源(您仍然可以直接访问的资源),是保持&#34; smart&#34;只要您需要访问资源,指针/所有者就会生效。

所以&#34; smart&#34;指针(拥有对象)需要命名。此外,我不确定你是否真的想隐藏这个事实,即它是auto读者视角的智能指针。

std::shared_pointer<Bar> foo = getSharedPointer();
// use foo.get()

您可能希望隐藏托管对象的确切类型:

std::shared_pointer<auto> foo = getSharedPointer();