是否存在无法锁定(提升为shared_ptr)的weak_ptr?如果没有,为什么?

Tay*_*ter 1 c++ shared-ptr weak-ptr unique-ptr c++11

也许以前曾经问过这个问题,但我从未找到过满意的答案.此外,为简单起见,我假设我在谈论单线程应用程序.

所以,我多次听到的是,如果你有一个拥有的对象并且它的生命周期得到保证,你应该用原始指针引用它.对象的所有者将使用unique_ptr,并根据需要分发原始指针.

但是,如果该对象是非拥有的,并且生命周期无法保证怎么办?然后你可以使用weak_ptr,是的.但是,任何交给weak_ptr的人都可能是顽皮的并保持锁定状态,这样对象的所有者就不会导致对象被破坏.有时这可能不是问题,但有时也是如此.例如,当拥有的对象表示某个必须在特定时间放弃的系统资源时.

你可能会说"好吧,那么你应该确保没人阻止weak_ptr锁定!" 但是从OO设计的角度来看,这在我看来并不理想,因为它在"所有者"对象和从中获取weak_ptr的任何对象之间创建了依赖关系.您也可以创建参数"您不需要返回const引用;您应该确保没有人修改引用."

有了Qt,你有QPointer,这基本上就是我正在寻找的.它检查对象是否已被销毁,但它无法阻止对象被销毁.我意识到这不是线程安全的,但同样,我在谈论单个线程的上下文.

那么为什么C++ 11没有类似的东西呢?我确信我可以在weak_ptr周围创建一个包装器来完成我所追求的目标.但是我想知道我是不是错了.

Dav*_*rtz 6

不,它不存在是因为即使对于单个线程它也是不安全的.考虑:

void some_function (super_weak_ptr foo)
{
    foo->some_function();
}
Run Code Online (Sandbox Code Playgroud)

如果some_function(通过间接路径)导致对象被销毁会发生什么?在你说永远不会发生之前,是的,它可以.例如:

void got_some_data (some_type whatObject, some_other_type whatData)
{
    super_weak_ptr object = findObject (whatObject);
    if (object)
        object->youGotMail (whatData);        
}
Run Code Online (Sandbox Code Playgroud)

现在,假设该youGotMail函数实现了对象现在获得了所需的最后一点数据并且其作业已完成,它可能会破坏该对象,现在我们正在对不再存在的对象运行函数.

如果你想要一个原始指针,你知道在哪里找到一个.创建一个比原始指针更安全的"智能"指针没有多大意义.

因此,如果您不管理对象的生命周期,则需要能够在对该对象执行任何操作之前锁定该对象.

  • @ Cheersandhth.-Alf提议的`weak_ptr`替代方案基本上是一个原始指针.如果你想要一个原始指针,那么只需使用一个原始指针.不要在上面涂上口红,并假装它比它更好. (4认同)
  • @BenVoigt如果你知道在调用`youGotMail`期间对象的生命周期永远不会结束,那么弱指针并不能真正为你买任何东西.弱指针适用于您不知道生命周期的情况. (3认同)
  • @ Cheersandhth.-Alf根据他的建议,你总是有一个竞争条件,因为你有原始指针,但没有办法保持对象存在,你不能控制它的生命周期.所以它是一个类似原始指针的东西.如果你不控制某些东西的生命周期,你需要一种方法来保持它的活着,而你却不知道它,这不提供一个,所以它是原始指针. (2认同)
  • @TaylorBrandstetter问题是很难确定你没有任何这些循环依赖.当您使用智能指针时,任何抛弃引用的代码都可能会破坏您通常希望销毁该对象的对象和代码可能最终不会破坏它,因为其他一些代码仍然有一个强大的指针指向它,导致你没想到的代码会破坏它后来破坏它.我们使用智能指针,所以这些东西不会咬我们,建议的"非常弱的指针"将很难安全使用. (2认同)