【问题标题】:shared pointer and raw pointer lifetime共享指针和原始指针生命周期
【发布时间】:2017-01-27 01:15:21
【问题描述】:

有人能简单解释一下这不起作用的原因吗:

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

...

auto foo = getSharedPointer().get();

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

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

【问题讨论】:

  • 无法找到标准库或常见第三方中记录的getSharedPointer。不知道会发生什么。建议添加更多信息。

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


【解决方案1】:

对于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

【讨论】:

  • 请添加注释,spb 只会持续到范围结束
【解决方案2】:
auto foo = getSharedPointer().get();

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

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

这里getSharedPointer() 总是返回不共享托管对象的shared_ptruse_count() 为 1),所以当最后一个shared_ptr 的副本被销毁时,该对象被销毁并且指向对象无效。

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

正确使用智能指针或任何“拥有”(控制其生命周期)其他资源(您仍然可以直接访问的资源)的类,是为了让“智能”指针/所有者保持活动状态只要您需要访问资源。

因此需要命名“智能”指针(拥有对象)。另外,我不确定您是否真的想用auto 隐藏读者认为它是智能指针的事实。

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

您可能想要隐藏托管对象的确切类型:

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

【讨论】:

  • 不得不再次参考代码以查看唯一 ptr 在应用程序中是否更有意义,但感谢您的提醒;生病检查一下。另外,您准确地解释了我需要了解的有关临时对象和生命周期的信息,由于对 cpp 来说是新手,因此我未能教育自己。谢谢。
猜你喜欢
  • 1970-01-01
  • 2021-08-12
  • 1970-01-01
  • 2020-02-13
  • 2014-06-25
  • 2021-05-17
  • 1970-01-01
  • 1970-01-01
  • 2021-03-10
相关资源
最近更新 更多