c++:Loki StrongPtr看起来不安全,是这样吗?

w1e3prcc  于 2023-08-09  发布在  其他
关注(0)|答案(2)|浏览(101)

我目前正在研究最流行的智能Ptr实现,如boost共享和弱指针以及loki Smart and Strong pointer,因为我想实现我自己的,从我的理解来看,Loki强指针对我来说看起来不安全,但我宁愿认为我理解错了,所以我想讨论它是否安全。我认为它不安全的原因是,据我所知,它没有足够小心地对待弱指针(即StrongPtr,其中false表示其弱):
例如解引用函数:

PointerType operator -> ()
{
KP::OnDereference( GetPointer() ); //this only asserts by default as far as i know
//could be invalidated right here
return GetPointer();
}

字符串
在多线程环境中,弱指针可以随时失效,因此此函数可能返回失效的Ptr。
据我所知,你要么必须创建一个你正在取消引用的ptr的strongPtr示例,以确保它不会在中途失效。我想这也是为什么boost不允许你在没有创建一个shared_ptr示例的情况下取消引用weak_ptr的原因。Lokis StrongPtr构造函数也有同样的问题。
这是一个问题,还是我阅读错了src?

ao218c7q

ao218c7q1#

关于assert的使用,在一个空的StrongPtr<>示例上使用operator->是一个 * 编程错误 *;也就是说,在取消引用StrongPtr<>示例之前,*caller * 有责任确保StrongPtr<>示例非空。为什么需要比assert更多的东西?也就是说,如果你认为其他行为比assert更合适,那么这正是该策略的目的。
这是前置条件和后置条件的根本区别;这里有一个很长但很好的主题:comp.lang.c++.moderated: Exceptions.特别阅读D.亚伯拉罕,他详细解释了我所说的众所周知的事实。;-]
关于StrongPtr<>的线程安全性,我怀疑Loki的大多数版本早于任何严重的线程安全问题;另一方面,boost::shared_ptr<>std::shared_ptr<>被明确地 * 保证 * 是线程安全的,所以我确信它们的实现为研究提供了一个“更好”(尽管复杂得多)的基础。

v64noz0r

v64noz0r2#

仔细阅读后,我想我看到了其中的道理。
StrongPtr对象是双重的,因为它们同时表示StrongWeak引用。
assert的机制在Strong版本上工作得很好。在Weak版本中,调用者有责任确保引用的对象将存在足够长的时间。这可以通过以下两种方式实现:

  • 如果您知道您有Strong版本,则会自动执行此操作
  • 手动创建Strong示例

wrt std::shared_ptr的好处是,当您已经知道该项目将超过您的使用寿命时,可以避免创建新对象。这是一个有争议的设计决策,但对Maven来说效果很好(Alexandrescu无疑是其中之一)。它可能没有针对普通用户(我们),因此强制执行Strong版本会更好。
人们也可以说,事后诸葛亮总是更容易批评。Loki,尽管它很伟大,但已经很老了。

相关问题