2

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

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

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

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

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

编辑:背景更新。
EDIT2:问题已更新。
EDIT3:找到直接的解决方案。有兴趣可以看我的回答。

4

3 回答 3

2

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

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

于 2013-04-26T15:15:24.833 回答
2

好吧,这实际上取决于您的需求,更具体地说,您希望在所有权方面实现什么:

  1. 你应该vector自己的shared_ptr<T>吗?(或者你可以只存储指针?)
  2. 你应该vector自己的T*吗?

然后有多种解决方案。

  1. 完全所有权:只需T*shared_ptr<T>
  2. 部分所有权:如前所述,您可以shared_ptr<T>使用无操作删除器实例化 a 来包装T*
  3. 没有所有权:只需打开shared_ptr<T>使用.get()并仅存储T*
于 2013-04-26T15:21:52.453 回答
1

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

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;
}

编辑:修订、共享无效、自定义删除器。

于 2013-04-26T16:03:38.993 回答