使用C ++共享指针的别名构造函数和空的共享指针 [英] Using C++ shared pointer's aliasing constructor with an empty shared pointer

查看:217
本文介绍了使用C ++共享指针的别名构造函数和空的共享指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

std :: shared_ptr具有一个别名构造函数,该函数允许新创建的shared_ptr与现有的共享指针共享状态,同时指向其他对象.

std::shared_ptr has an aliasing constructor that allows newly created shared_ptr to share state with an existing shared pointer while pointing to some other object.

我当时正在考虑滥用此构造函数,以将指向全局对象的指针放置在shared_ptr中:

I was thinking about abusing this constructor to put pointer to some global object inside 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;
}

我的问题是:合法吗?该代码可在主要编译器上成功运行.

My question is: Is it legal? The code successfully works on major compilers.

请注意,我不问这是否是一件好事.我确实知道,有一种使用无操作删除器将指向全局对象的指针放入shared_ptr中的规范方法.如果合法,这也有点令人不安,因为有可能具有可取消引用的shared_ptr,弱指针始终过期:

Note, that I do not ask if it's a good thing to do. I do understand that there's a canonical way of putting pointers to global objects into shared_ptr using no-op deleter. It is also a bit disturbing if it is legal, because it would be possible to have dereferenceable shared_ptr, weak pointers to which are always expired:

    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
    }

推荐答案

众所周知,在当前解决方案中,puse_count()为零,这就是weak_ptr过期的原因.根据C ++草案N4296,这似乎可以:

As you already know, with your current solution, p has a use_count() of zero, that's why the weak_ptr is expired. This seems to be ok, according to the C++ draft N4296:

20.8.2.2.1 shared_ptr构造函数 [util.smartptr.shared.const]
模板shared_ptr(const shared_ptr& r,T * p)noexcept;
13效果:构造一个shared_ptr实例,该实例存储p并与r共享所有权.
14后置条件:get()== p&& use_count()== r.use_count()
15 [注意:为避免指针悬空的可能性,此构造函数的用户必须确保p 至少在r的所有权组被销毁之前一直保持有效. —尾注]
16 [注意:此构造函数允许创建一个空的shared_ptr实例,其中存储了一个非null 指针. —尾注]

20.8.2.2.1 shared_ptr constructors [util.smartptr.shared.const]
template shared_ptr(const shared_ptr& r, T* p) noexcept;
13 Effects: Constructs a shared_ptr instance that stores p and shares ownership with r.
14 Postconditions: get() == p && use_count() == r.use_count()
15 [ Note: To avoid the possibility of a dangling pointer, the user of this constructor must ensure that p remains valid at least until the ownership group of r is destroyed. — end note ]
16 [ Note: This constructor allows creation of an empty shared_ptr instance with a non-null stored pointer. — end note ]

20.8.2.2.2 shared_ptr析构函数[util.smartptr.shared.dest]
〜shared_ptr();
1种效果:
(1.1)— 如果*此为空或与另一个shared_ptr实例(use_count()> 1)共享所有权, 没有副作用.
(1.2)—否则,如果*这拥有一个对象p和一个删除器d,则调用d(p).
(1.3)—否则,*这拥有一个指针p,而删除p称为

20.8.2.2.2 shared_ptr destructor [util.smartptr.shared.dest]
~shared_ptr();
1 Effects:
(1.1) — If *this is empty or shares ownership with another shared_ptr instance (use_count() > 1), there are no side effects.
(1.2) — Otherwise, if *this owns an object p and a deleter d, d(p) is called.
(1.3) — Otherwise, *this owns a pointer p, and delete p is called

强调我的.
您可以使用以下代码代替,该代码给出shared_ptruse_count()为1:

emphasis mine.
You could use the following instead which gives a shared_ptr with a use_count() of one:

std::shared_ptr<int> p(&global, [](int*){});

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

This uses an empty custom deleter.

这篇关于使用C ++共享指针的别名构造函数和空的共享指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆