【问题标题】:Is it necessary to use a unique_ptr in this case?在这种情况下是否有必要使用 unique_ptr ?
【发布时间】:2017-08-31 06:37:39
【问题描述】:

所以,这是我正在创建的一个类的示例:

typedef struct st{
    int counter;
    int fields[128];
}stEx;

class Foo {
    stEx *E;
    int index;
public : 
    Foo(){
        this->index = 0;
        this->E = new stEx;
    }
    ~Foo(){
        delete E;
    }
}

由于我希望 E 单独成为 Foo 对象的实例,因此 E 对象必须在 Foo 对象被销毁时自动销毁,因此不应超过该对象。这就是我遇到智能指针,尤其是唯一指针的概念的原因。

但是,我似乎无法理解为什么需要使用唯一指针。 以及如何销毁/释放唯一指针?

这是我对唯一指针的尝试。

#include <memory>

typedef struct st{
    int counter;
    int fields[128];
}stEx;

class Foo {
    std::unique_ptr<stEx> E;
    int index;
public : 
    Foo(){
        this->index = 0;
        this->E = std::unique_ptr<stEx>(new stEx());
    }
    ~Foo(){
        E.release; // ?
    }
}

提前致谢!

【问题讨论】:

  • 使用release 会破坏目的。 unique_ptr 的目的是消除记住释放资源的负担。 std::unique_ptr::release 则相反,称其为您希望对象被自动删除的声明。
  • 考虑使用std::make_unique&lt;stEx&gt;() 而不是new
  • 你为什么还要在这里使用指针?为什么不让它成为该类的普通值成员,然后你会得到自动清理。
  • 尝试复制构造或分配Foo 对象。
  • 如果你想复制构造 Foo:见stackoverflow.com/questions/16030081/…

标签: c++ pointers


【解决方案1】:

这样做的惯用方法是:

class Foo
{
    std::unique_ptr<stEx> E;
    int index;
public: 
    Foo() : E(std::make_unique<stEx>()), index(0)
    {}
};
  • 使用初始化列表
  • 使用 make_unique(从不输入 new
  • 没有析构函数

此类型将自动启用移动,但禁用复制

【讨论】:

    【解决方案2】:

    在这种情况下,我看不出有必要使用unique_ptr,因为你只有一个对象,而且它的生命周期在类的生命周期之内,所以你可以只使用一个成员。

    typedef struct st{
        int counter;
        int fields[128];
    }stEx;
    
    class Foo {
        stEx E;
        int index;
    public : 
        Foo(){
            index = 0;
        }
    }
    

    此外,您不需要使用指针 this 来访问类成员。

    而且不需要调用:

    E.release; // ?
    

    用这一行分配的内存:

    this->E = std::unique_ptr<stEx>(new stEx());
    

    加上智能指针句柄的开销,当智能指针超出我们的范围时被释放。

    在你的情况下隐含在Foo析构函数中。

    注意:unique_ptr::release() 释放托管对象的所有权 如果您需要 new stEx 对象不再归 E 所有。 你必须:

    Foo* stExPtr = up.release(); //stEx is no longer owned by unique_ptr
    delete stExPtr;
    

    【讨论】:

      【解决方案3】:

      在析构函数中,编译器会自动为类的所有非静态成员插入调用析构函数。因此,您不必为此添加任何代码。

      【讨论】:

        【解决方案4】:

        以及如何销毁/释放唯一指针?

        你没有。这就是unique_ptr 的全部意义:Foo::EFoo 一起被破坏,并且也破坏了它的指针。无需手动清理。

        此外,您几乎不必使用release。这个函数使unique_ptr 释放它的指针,因为它不会破坏它,你必须像以前一样自己delete它。

        【讨论】:

        • @FrançoisAndrieux 已添加。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-31
        • 2023-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多