【问题标题】:Storing of std::weak_ptr<void> and using static_pointer_cast存储 std::weak_ptr<void> 并使用 static_pointer_cast
【发布时间】:2019-11-23 14:43:55
【问题描述】:

如果将std::weak_ptrstatic_pointer_cast 一起存储,引用计数是否仍然有效?

这是一个非常简化的示例(注意SmallBoxBigBox 类几乎完全相同):

#define OWNER_SMALLBOX    1
#define OWNER_BIGBOX      2

class Object
{
    private:
        std::weak_ptr<void> owner;
        int ownerType;

    public:

        void doSomethingIfOwnerStillExist()
        {
            if(std::shared_ptr<void> ownerShared = owner.lock())
            {
                switch(ownerType)
                {
                    case OWNER_SMALLBOX:
                        std::shared_ptr<SmallBox> smallBox = std::static_pointer_cast<SmallBox>(ownerShared);
                    break;

                    case OWNER_BIGBOX:
                        std::shared_ptr<BigBox> bigBox = std::static_pointer_cast<BigBox>(ownerShared);
                    break;
                }//switch
            }
        }

        Object(std::shared_ptr<void> _owner, int _ownerType)
        {
            owner = _owner;
            ownerType = _ownerType;
        }
};

class SmallBox
{
    private:
        std::list< std::shared_ptr<Object> > objects;

    public:

        static void addObject(std::shared_ptr<SmallBox> _smallBox)
        {
            std::shared_ptr<void> owner = std::static_pointer_cast<void>(_smallBox);
            objects.push_back(std::make_shared<Object>(owner, OWNER_SMALL_BOX));
        }
};

class BigBox
{
    private:
        std::list< std::shared_ptr<Object> > objects;
    public:

        static void addObject(std::shared_ptr<BigBox> _bigBox)
        {
            std::shared_ptr<void> owner = std::static_pointer_cast<void>(_bigBox);
            objects.push_back(std::make_shared<Object>(owner, OWNER_BIGBOX));
        }
};

我知道我可以让SmallBoxBigBox 类继承自GeneralBox 类,并将void 类型替换为GeneralBox 类型,但weak_ptr 可以指向多个其他类型也是如此,这使得继承变得非常庞大和笨拙。

我很好奇shared_ptr 是否仍然可以跟踪转换为 void 的弱指针。

【问题讨论】:

  • 如果你真的需要转换回doSomethingIfOwnerStillExist 中的原始类型,我还建议使用std::variant&lt;std::weak_ptr&lt;SmallBox&gt;, std::weak_ptr&lt;BigBox&gt;&gt; 之类的东西,因为它会管理你所做的所有ownerType 跟踪自动为你。或者更好的是,正如您所提到的,使用带有doSomethingIfOwnerStillExist 将使用的接口的基类。由于无论如何您都必须跟踪Object 中的所有可能类型,所以我不认为将接口添加到每个类会更复杂。
  • 我会查找 std::variant。对不起,我不能减少例子,我会看看我能做什么。

标签: c++ smart-pointers static-cast weak-ptr


【解决方案1】:

如果我正确理解您的问题,那么您是在询问 std::static_pointer_cast 是否会返回与调用它的参数共享所有权的 std::shared_ptr

答案是肯定的。

addObject 中的owner 将与addObject 的函数参数共享所有权,对象中的owner 将引用同一控制块,@ 中的ownerSharedsmallBoxbigBox 也将引用相同的控制块987654330@.

但是请注意,存储在objects 中的shared_ptr 是完全不相关的,因为它们是通过调用std::make_shared 创建一个新的Objects 来初始化的,该Objects 将只由objects 拥有。

如果std::static_pointer_cast 不返回与参数共享所有权的实例,它将毫无用处,因为如果不是,它将不可避免地导致托管指针的双重删除。

【讨论】:

  • 感谢您的回答。我忘记将创建的对象添加到示例中的列表中。它将存储在“Box”类中。
  • 请注意,这些伪“强制转换”是通过“别名构造函数”创建别名 shared_ptr 的特殊情况。您甚至可以拥有一个指向成员子对象、数组元素或由shared_ptr“共同拥有”的对象所拥有的任何对象的智能指针。
猜你喜欢
  • 2011-08-29
  • 1970-01-01
  • 2016-08-03
  • 1970-01-01
  • 2014-12-17
  • 2018-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多