【问题标题】:unique_ptr: How to safely share raw pointerunique_ptr:如何安全地共享原始指针
【发布时间】:2012-07-12 16:06:11
【问题描述】:

我正在创建一个由unique_ptr 管理的类,但由于各种原因,我需要让实现访问指向该对象的原始指针。但是我想确保用户不会无意中删除底层对象。我想出了以下示例代码:
(它是树结构的一部分,我需要能够查看树节点的成员而不实际分离它们。shared_ptr 在这种情况下似乎有点矫枉过正。)

#include <memory>

using namespace std;

class unOnly
{
    ~unOnly() {}
public:
    unOnly() {}
    friend class default_delete<unOnly>;
};

int main()
{
    unique_ptr<unOnly> ptr(new unOnly());
}

这在 gcc 4.4.5 中为我编译。但是,我可以确定在所有实现中default_delete 是实际deletes 对象,而不是一些私有实现类?我应该自己写删除器来确定吗?

【问题讨论】:

    标签: c++ c++11 unique-ptr


    【解决方案1】:

    为什么不

    class unOnly
    {
        unOnly() {}
        ~unOnly() {}
        struct deleter { void operator()(unOnly* x) { delete x; }};
    
    public:
        typedef std::unique_ptr<unOnly, deleter> handle;
    
        static handle create() { return handle(new unOnly); }
    };
    
    auto x = unOnly::create();
    

    ?甚至

    class unOnly
    {
        ~unOnly() {}
        struct deleter { void operator()(unOnly* x) { delete x; }};
    
    public:
        unOnly() {}
        typedef std::unique_ptr<unOnly, deleter> handle;
    };
    
    unOnly::handle x(new unOnly);
    

    (我更喜欢前者,但后者可能更符合您的要求)

    【讨论】:

    • 我喜欢第一个解决方案;我本来想给它一个私有构造函数,但是unique_ptr 不构造它拥有的对象。
    • 虽然您提供了两种可移植的替代方案,但您并没有真正回答这个问题,即询问 given 代码是否可移植。
    • @RobKennedy:Praetorian 已经用标准报价回答了这个问题,你可以看到它是否定的。 OP 想要有所作为,我们随时为您提供帮助。
    【解决方案2】:

    unique_ptr 的要点(除了拥有一个拥有它的指针的对象之外)是您可以将自定义删除器传递给它,因此只需编写一个而不是做其他事情是有意义的,这似乎不必要地复杂。

    【讨论】:

    • 是的,但是这样做意味着该类的所有用户都需要将其实例化为unique_ptr&lt;unOnly&gt; ptr(new unOnly(), custom_deleter);。或者他不得不求助于制造工厂函数来分配unOnly 的实例。
    【解决方案3】:

    引用标准:

    20.7.1 类模板 unique_ptr

    6。 [...]

      template<class T, class D = default_delete<T>> class unique_ptr;
    

    20.7.1.1.1

    1 类模板 default_delete 用作类模板 unique_ptr 的默认删除器(销毁策略)。

    因此,unique_ptr 的实现似乎需要使用default_delete 作为默认删除器。

    编辑:
    但这并不意味着您的方法是万无一失的,请参阅下面的@RMartinhoFernandes 评论。

    【讨论】:

    • 但是你可以拥有void default_delete&lt;T&gt;::operator()(T* t) { some_internal_implementation_class::do_the_deleting(t); },而在那儿交友对你没有帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    • 2023-01-08
    • 1970-01-01
    • 2021-03-10
    相关资源
    最近更新 更多