可以这样实施:
std::shared_ptr<T> operator->() {
auto shared = lock();
if(shared == nullptr) {
throw std::bad_weak_ptr(); // or some other exception
}
return shared;
}
为什么weak_ptr的作者决定不拥有operator-&gt;?(他们必须想到它)
我可以想到潜在的原因,但我想知道官方原因是什么,如果存在的话。可能的原因:
如果您对返回的shared_ptr的生命周期感到困惑,请参阅this paper.
另外,有人问为什么如果你期望它没有过期,会使用weak_ptr?答案:周期。
答案 0 :(得分:9)
original proposal weak_ptr
未包含operator->
的重载。
我从未查看过每次会议的会议记录,但是已经按照所讨论的内容进行了讨论,并且不记得有人提到应该添加它。因此,它不存在的“官方”原因很可能是没有人提议将其添加。
如果你想回到非常的开头,大部分内容都来自John Ellis和David Detlef的Safe, Efficient Garbage Collection for C++论文,来自Usenix 1994.其中包括weakptr
在附录B中键入。这有点不同(weakptr::pointer
直接返回一个指针,如果指针已被销毁,则返回空指针),但仍然没有使用运算符重载来完成这项工作。
Greg Colvin写了original proposal to add counted_ptr
标准。其counted_ptr
基本上与现在称为shared_ptr
的内容相同,但不包含与weak_ptr
类似的任何内容。
在委员会拒绝counted_ptr
提案并采用auto_ptr
之后不久,counted_ptr
的基本想法在Boost上得以恢复。我不记得有任何关于添加operator->
的讨论,但它在那里“活了”很长时间以至于完全有可能有人在没有意识到它的情况下提出它。
答案 1 :(得分:6)
我会尽力说明为什么这不是一个好主意:
有一点是清晰度:
ptr->foo();
ptr->bar();
这里的问题是在第一次和第二次调用之间的某个地方,ptr可能会通过一个不同的线程(这将是一个竞争条件)或者通过调用foo
的副作用而到期。
另一件事是对称:当我有一个指针时,我期望运算符*
,->
和隐式转换为布尔值。有些人可能不同意,但运营商*
和->
经常重合。我很惊讶这不是这种情况。
也就是说,使用C ++ 11,它写起来太容易了:
if (auto p = ptr.lock()) {
p->foo();
p->bar();
}
知道ptr
是weak_ptr
,该代码的含义和行为非常明确。