c++ - 是否应该使用 unique_ptr 来更轻松地实现 "move"语义?

标签 c++ c++11 move-semantics unique-ptr

编辑:制作FooBar不那么琐碎,直接替换为 shared_ptr<>更难。


应该unique_ptr<>用作实现 move 语义的更简单方法?

对于像这样的类

class Foo
{
    int* m_pInts;
    bool usedNew;
    // other members ...

public:
    Foo(size_t num, bool useNew=true) : usedNew(useNew) {
        if (usedNew)
            m_pInts = new int[num];
        else
            m_pInts = static_cast<int*>(calloc(num, sizeof(int)));
    }
    ~Foo() {
        if (usedNew)
            delete[] m_pInts;
        else
            free(m_pInts);
    }

    // no copy, but move
    Foo(const Foo&) = delete;
    Foo& operator=(const Foo&) = delete;
    Foo(Foo&& other) {
        *this = std::move(other);
    }
    Foo& operator=(Foo&& other) {
        m_pInts = other.m_pInts;
        other.m_pInts = nullptr;
        usedNew = other.usedNew;
        return *this;
    }
};

随着数据成员的增加,实现 move 变得更加乏味。但是,可 move 数据可以放在单独的 struct 中。 ,其中一个实例由 unique_ptr<> 管理.这允许 =default用于 move :

class Bar
{
    struct Data
    {
        int* m_pInts;
        bool usedNew;
        // other members ...
    };
    std::unique_ptr<Data> m_pData = std::make_unique<Data>();

public:
    Bar(size_t num, bool useNew = true) {
        m_pData->usedNew = useNew;
        if (m_pData->usedNew)
            m_pData->usedNew = new int[num];
        else
            m_pData->m_pInts = static_cast<int*>(calloc(num, sizeof(int)));
    }
    ~Bar() {
        if (m_pData->usedNew)
            delete[] m_pData->m_pInts;
        else
            free(m_pData->m_pInts);
    }

    // no copy, but move
    Bar(const Bar&) = delete;
    Bar& operator=(const Bar&) = delete;
    Bar(Bar&& other) = default;
    Bar& operator=(Bar&& other) = default;
};

unique_ptr<> 的内存除外实例总是在堆上,这样的实现还存在哪些其他问题?

最佳答案

是的。您正在寻找的是零规则(作为三/五规则的 C++11 扩展)。通过让您的数据都知道如何复制和 move 它们自己,外部类不需要编写任何 特殊成员函数。编写这些特殊成员可能容易出错,因此不必编写它们可以解决很多问题。

所以 Foo 会变成:

class Foo
{
    std::unique_ptr<size_t[]>  data;

public:
    Foo(size_t size): data(new size_t[size]) { }
};

而且这很容易证明其正确性。

关于c++ - 是否应该使用 unique_ptr 来更轻松地实现 "move"语义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40851598/

相关文章:

c++ - 检查是否有效的模板特化

c++11 - C++ : For which objects, 是 "moved"意味着超过 "staying valid"?

c++ - 返回非静态本地对象时,选择复制构造函数而不是 move 构造函数

c++ - QML:如何将动态创建的组件与自定义的内部对象一起使用?

c++ - 尝试在另一个类的头文件中使用对象,出现 “redefinition of class”错误

c++ - 自动创建继承实例

c++ - 显式默认析构函数禁用类中的默认 move 构造函数

c++ - 将多维 C++ 数组作为一个连续 block (在堆上)访问是否有效

C++:从类型索引获取父类(super class)类型索引

c++ - 三个原子变量上的 CompareAndExchange