1

我目前正在研究最流行的智能 Ptr 实现,例如提升共享指针和弱指针以及 loki智能和强指针,因为我想实现自己的,据我所知,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?

4

2 回答 2

3

Regarding the use of assert, it's a programming error to use operator-> on an empty StrongPtr<> instance; i.e., it is the caller's responsibility to ensure that the StrongPtr<> instance is non-empty before dereferencing it. Why should anything more than an assert be needed? That said, if you deem some other behavior more appropriate than assert, then that's exactly what the policy is for.

This is a fundamental difference between preconditions and postconditions; here's a long but very good thread on the subject: comp.lang.c++.moderated: Exceptions. Read in particular the posts by D. Abrahams, as he explains in detail what I'm stating as understood fact. ;-]

Regarding the thread-safety of StrongPtr<>, I suspect most of Loki predates any serious thread-safety concerns; on the other hand, boost::shared_ptr<> and std::shared_ptr<> are explicitly guaranteed to be thread-safe, so I'm sure their implementations make for a "better" (though much more complicated) basis for study.

于 2011-05-03T10:00:20.223 回答
0

仔细阅读后,我想我明白了其中的道理。

StrongPtr对象是双重的,因为它们代表StrongWeak引用。

的机制在一个版本assert上效果很好。Strong在一个Weak版本中,调用者有责任确保引用的对象能够存活足够长的时间。这可以实现:

  • 自动,如果你知道你有一个Strong版本
  • 手动,通过创建一个Strong实例

好处std::shared_ptr是,当您已经知道该项目将超过您的使用期限时,您可以避免创建新对象。这是一个值得商榷的设计决定,但对专家来说非常有用(Alexandrescu 无疑是其中的一员)。它可能没有针对普通用户(我们),因此强制执行一个Strong版本会更好恕我直言。

人们也可以争辩说,事后看来,批评总是更容易。Loki,尽管它很伟大,但它已经过时了。

于 2011-05-03T12:20:41.810 回答