同一容器中的共享指针和原始指针

Shared pointers and raw pointers in same container

本文关键字:指针 共享 原始      更新时间:2023-10-16

我需要同时用共享指针和原始指针填充容器。

我猜shared_ptr<T>可能会被迫表现得像T*,如果用无操作删除器和无操作(de)分配器构造?

或者可能有一个通用的智能指针,它绑定到不同的(智能和原始)指针类型?

或者可能是shared_ptr可以指向一个对象,但管理另一个(nullptr)相同类型的对象的生命周期?

的背景。我有一个简单的组件系统。有些组件是内置的,不需要管理,原始指针就足够了。其他组件是外部dll,它们必须在请求时附加,并在从"会话"中删除时分离。对于后者,我使用包装器组件,它将在销毁时分离DLL。

EDIT: Background updated.
EDIT2: Question updated.
EDIT3: find straight solution。如果有兴趣,可以看看我的答案。

一般来说,没有;容器只包含一种类型的对象。

您可以使用某种boost::variant<shared_ptr<T>, T*>对象作为包含对象。但你需要访客来访问它的元素。或者,您可以给boost::shared_ptr一个特殊的deleter对象,它实际上不会删除指向的值。

嗯,这真的取决于你的需求是什么,更具体地说,你想在所有权方面实现什么:

    你的vector应该拥有shared_ptr<T>吗?(或者你可以直接存储指针吗?)你的vector应该拥有T*吗?

有多种解决方案。

  1. 完全所有权:只需将T*封装在常规shared_ptr<T>
  2. 部分所有权:如前所述,您可以实例化shared_ptr<T>,使用无操作删除器来包装T*
  3. 没有所有权:只使用.get()打开shared_ptr<T>,只存储T*

共享指针可能指向一个对象,但管理另一个对象的生命周期。奇怪的是,它可能什么都做不了,但仍然指向一些东西。有一个特殊的构造函数,它接受另一个共享指针,用于确定要共享哪个对象。可以在其中传递空的共享指针。

template <typename T>
std::shared_ptr<T> fake_shared(T *ptr)
{
    std::shared_ptr<T> dummy (nullptr); // we have nothing to manage;
    std::shared_ptr<T> faked (dummy, ptr); // but we have something to point to;
    return faked;
}

此外,我们可以利用两个事实。首先,这个构造函数将接受任何(其他)类型的共享指针。其次,std::shared_ptr<void>是合法的,可以用来更清楚地表达我们的意图。

template <typename T>
std::shared_ptr<T> fake_shared(T *ptr)
{
    std::shared_ptr<void> dummy (nullptr); // we have really nothing to manage;
    std::shared_ptr<T> faked (dummy, ptr); // but we have something to point to;
    return faked;
}

或者,可以使用构造函数,该构造函数接受自定义删除器,并将无操作删除器传递给它。

template <typename T>
std::shared_ptr<T> fake_shared(T *ptr)
{
    std::shared_ptr<T> faked (ptr, [](T *){}); // won't be deleted;
    return faked;
}

EDIT:修改,共享空白,自定义删除。