unique_ptr 的移动求和运算符

The move sum operator with unique_ptr

我理解指针管理的机制有点复杂。

我尝试通过以下方法减少 class 成员的复制操作:

#include <iostream>
#include <vector>

class Shape {

public:

    std::unique_ptr<int> x;

    Shape(const Shape& val) = delete; // will be delete by default by compiler?

    Shape& operator=(const Shape& val) = delete; // will be delete by default by compiler?

    Shape(Shape&& val) noexcept {
        this->x = std::move(val.x);
    }

    Shape& operator=(Shape&& val) noexcept {
        std::cout << "Move operator=" << std::endl;
        this->x = std::move(val.x);
        return *this;
    }

    Shape() : x(std::unique_ptr<int>(new int)) {
        std::cout << "Constructor Shape" << std::endl;
    }

    Shape(int v) : x(std::unique_ptr<int>(new int(v))) {
        std::cout << "Constructor Shape (by value)" << std::endl;
    }

    virtual ~Shape() {
        std::cout << "Destructor Shape" << std::endl;
    };

    Shape operator+(const Shape& val) {

        std::cout << "Move sum" << std::endl;
        Shape res(*x + *val.x);
        return res;
    }
};

int main()
{

    Shape a(1);
    Shape b(3);

    Shape res = a + b;

    std::cout << "Value a is (" << *(a.x) << ")" << std::endl;
    std::cout << "Value b is (" << *(b.x) << ")" << std::endl;
    std::cout << "Value res is (" << *(res.x) << ")" << std::endl;

};

结果是:

构造函数形状(按值) 构造函数形状(按值) 移动总和 构造函数形状(按值) 析构形状 值 a 是 (1) 值 b 是 (3) 值 res 是 (4) 析构形状 析构形状 析构函数形状

将复制构造函数和复制运算符=标记为 "deleted" 是个好主意还是我可以删除这些行? std::move 运营商一个人有多贵?

将复制构造函数和复制运算符=标记为“已删除”是个好主意还是我可以删除这些行?

您可以删除复制构造函数和复制运算符行的删除:

https://en.cppreference.com/w/cpp/language/copy_constructor 中删除了隐式声明的复制构造函数

The implicitly-declared or defaulted copy constructor for class T is defined as deleted if any of the following conditions are true:

  • ...
  • T has a user-defined move constructor or move assignment operator (this condition only causes the implicitly-declared, not the defaulted, copy constructor to be deleted).

std::move运营商一个人有多贵?

std::move 用于将值转换为 xvalue(eXpiring 值)。它没有成本(它是在编译时转换的)并且其含义是一旦你在一个对象上调用 std::move ,你不应该在之后使用它。例如,在您的代码中,a+b 隐式转换为 xvalue

您可以在此处找到有关 xvalues 的更多信息:https://en.cppreference.com/w/cpp/language/value_category