std :: shared_ptr有一个别名构造函数,允许新创建的shared_ptr在指向某个其他对象时与现有共享指针共享状态。
我在考虑滥用此构造函数将指针放到shared_ptr中的某个全局对象:
int global = 0;
int main()
{
// because we point to global object we do not need to track its lifetime
// so we use empty shared_ptr<void> as a provider of shared state
std::shared_ptr<int> p(std::shared_ptr<void>(), &global);
std::shared_ptr<int> pp = p;
return *pp;
}
我的问题是:合法吗?该代码成功地适用于主要编译器。
请注意,我不会问这是不是一件好事。我知道有一种规范的方法可以使用no-op deleter将指针指向全局对象到shared_ptr中。如果它是合法的,它也有点令人不安,因为它可能有可解除引用的shared_ptr,弱指针总是过期的:
std::shared_ptr<int> p(std::shared_ptr<void>(), &global);
std::weak_ptr<int> w = p;
if (p) // p is alive and well
{ // and w is not
*w.lock(); // and here program crashes
}
答案 0 :(得分:3)
如您所知,使用您当前的解决方案,p
的{{1}}为零,这就是use_count()
过期的原因。根据C ++草案N4296:
强调我的。20.8.2.2.1 shared_ptr构造函数 [util.smartptr.shared.const]
模板shared_ptr(const shared_ptr&amp; r,T * p)noexcept;
13效果:构造一个shared_ptr实例,用于存储p并与r共享所有权 14后置条件:get()== p&amp;&amp; use_count()== r.use_count()
15 [注意:为避免悬空指针的可能性,此构造函数的用户必须确保p 至少在r的所有权组被销毁之前仍然有效。 - 结束说明]
16 [注意:此构造函数允许创建一个非空存储的空shared_ptr实例 指针。 - 尾注]20.8.2.2.2 shared_ptr析构函数[util.smartptr.shared.dest]
〜shared_ptr的();
1效果:
(1.1) - 如果*这是空的或与另一个shared_ptr实例共享所有权(use_count()&gt; 1), 没有副作用。
(1.2) - 否则,如果*拥有对象p和删除者d,则调用d(p) (1.3) - 否则,*它拥有指针p,删除p称为
weak_ptr
,其中shared_ptr
为一个:
use_count()
这使用空的自定义删除器。