【发布时间】:2021-10-04 14:36:44
【问题描述】:
当有一个明确的理由认为“一个唯一的对象拥有指针”时,在 C++ 中处理共享指针的规范方法是什么?
例如,如果shared_ptr 是特定类的成员,该类负责初始化指针,那么可以说该类也应该对何时删除指针有最终决定权。
换句话说,可能是当所属类超出范围时(或者本身是delete'd,对指针的任何剩余引用都不再有意义。这可能是由于相关变量是被破坏类的成员。
这是一个示例的草图
class Owner
{
Owner()
{
p.reset(malloc_object(arguments), free_object);
}
std::shared_ptr<type> get() { return p; }
// seems strange because now something somewhere
// else in the code can hold up the deletion of p
// unless a manual destructor is written
~Owner()
{
p.reset(nullptr); // arduous
}
std::shared_ptr<type> p;
int a, b, c; // some member variables which are logically attached to p
// such that neither a, b, c or p make sense without each other
}
不能使用unique_ptr,因为这不允许get 函数返回指针,除非返回原始指针。 (这是可以接受的解决方案吗?)
unique_ptr 结合从 get 函数返回的 weak_ptr 可能有意义。但这不是有效的 C++。 weak_ptr 与shared_ptr 结合使用。
带有返回 weak_ptr 的 get 函数的 shared_ptr 比原始指针更好,因为要使用弱指针,必须将其转换为共享指针。如果引用计数已经为零并且对象已被删除,这将失败。
但是使用shared_ptr 会破坏这一点,因为理想情况下会选择unique_ptr,因为只有一个东西“拥有”指向的数据。
我希望这个问题足够清楚,因为我无法复制我正在使用的代码,所以很难解释。
【问题讨论】:
-
在我看来,显而易见的问题是为什么要传递指向对象内部状态的指针。由于您概述的原因,通常不鼓励这样做。
-
如果
Owner拥有p指向的type对象,那么p一开始就不应该是shared_ptr。但如果你真的需要,那么shared_ptr的别名构造函数可能在这里有用,如果你将Owner对象存储在shared_ptr中,然后让p指向type但依赖@987654343而是 @ 的共享所有权。 -
这不正是
weak_ptr存在的原因吗?您能否在您的用例中澄清weak_ptr的缺点。 -
shared_ptr 的问题在于它实际上是一个全局的——联合所有所有者。使用 unique_ptr 并分发非拥有的原始指针存在原始指针变成悬空指针的问题。这是一种权衡,两种方法都有优点/缺点,并且需要一定程度的纪律。 (无论哪种方式,暴露的对象都可以被改变,除非只暴露了 const 对象。)
-
我能想到在这里使用
shared_ptr的唯一原因是,如果你想绕过weak_ptrs,这样你就有了防止悬空的措施。
标签: c++ pointers shared-ptr unique-ptr ownership