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

问题描述 投票:0回答:2

我目前正在研究最流行的智能 Ptr 实现,例如 boost 共享指针和弱指针以及 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 不允许您在不先创建共享_ptr 实例的情况下取消引用weak_ptr 的原因。我认为 Lokis StrongPtr 构造函数也遇到同样的问题。

这是一个问题还是我读错了 src?

c++ smart-pointers c++-loki
2个回答
3
投票

关于

assert
的使用,在空的operator->实例上使用
StrongPtr<>
是一个
编程错误
;即,在取消引用之前确保 StrongPtr<> 实例非空是
调用者
的责任。为什么除了
assert
之外还需要其他东西?也就是说,如果认为其他行为比
assert
更合适,那么这正是该政策的目的。

这是前置条件和后置条件的根本区别;这里有一个关于这个主题的很长但非常好的线程:comp.lang.c++.moderated: Exceptions。请特别阅读 D. Abrahams 的帖子,他详细解释了我所说的理解事实。 ;-]

关于

StrongPtr<>
的线程安全,我怀疑 Loki 的大部分内容早于任何严重的线程安全问题;另一方面,
boost::shared_ptr<>
std::shared_ptr<>
明确地保证是线程安全的,所以我确信它们的实现为研究提供了“更好”(尽管更复杂)的基础。


0
投票

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

StrongPtr
对象是双重的,因为它们同时代表
Strong
Weak
引用。

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

  • 自动,如果您知道自己有
    Strong
    版本
  • 手动,通过创建
    Strong
    实例

std::shared_ptr
的好处是,当您已经知道该项目将超过您的使用期限时,您可以避免创建新对象。这是一个有争议的设计决策,但对于专家来说效果很好(Alexandrescu 无疑是其中之一)。它可能不是针对普通用户(我们)的,恕我直言,强制采用
Strong
版本会更好。

也有人可能会说,事后诸葛亮的批评总是更容易。

Loki
,尽管它很伟大,但它已经很古老了。

© www.soinside.com 2019 - 2024. All rights reserved.