使用C++共享指针的别名构造函数和一个空的共享指针

Гри*_*ков 7 c++ language-lawyer c++11

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;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:合法吗?该代码成功地适用于主要编译器.

请注意,我不会问这是否是一件好事.我知道有一种规范的方法可以使用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
    }
Run Code Online (Sandbox Code Playgroud)

ala*_*ain 3

正如您所知,对于您当前的解决方案,pause_count()为零,这就是weak_ptr过期的原因。根据 C++ 草案 N4296,这似乎没问题:

\n\n
\n

20.8.2.2.1 shared_ptr 构造函数[util.smartptr.shared.const]
\n 模板 shared_ptr(const shared_ptr& r, T* p) noexcept;
\n 13 作用:构造一个shared_ptr实例,存储p并与r共享所有权。
\n 14 后置条件: get() == p && use_count() == r.use_count()
\n 15 [ 注意:为了避免出现悬空指针,此构造函数的用户必须确保 p\n 保持有效至少直到r的所有权组被摧毁为止。\xe2\x80\x94 尾注]
\n 16 [ 注意:此构造函数允许使用非空存储指针创建一个空的shared_ptr 实例。\xe2\x80\x94 尾注]

\n\n

20.8.2.2.2 shared_ptr 析构函数 [util.smartptr.shared.dest]
\n ~shared_ptr();
\n 1 效果:
\n (1.1) \xe2\x80\x94如果 *this 为空或与另一个共享指针实例共享所有权 (use_count() > 1),\n 没有副作用。
\n (1.2) \xe2\x80\x94 否则,如果 *this 拥有对象 p 和删除器 d,则调用 d(p)。
\n (1.3) \xe2\x80\x94 否则,*this 拥有一个指针 p,并调用删除 p

\n
\n\n

强调我的。
\n您可以使用以下命令来代替,它给出的 ashared_ptruse_count()1:

\n\n
std::shared_ptr<int> p(&global, [](int*){});\n
Run Code Online (Sandbox Code Playgroud)\n\n

这使用了一个空的自定义删除器。

\n