Search code examples
c++copymoveoperator-keyword

The move sum operator with unique_ptr


It's a little complex for me to understand the mechanic of pointers management.

I try to reduce copy operations with a class members by this approuch:

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

};

The result is:

Constructor Shape (by value) Constructor Shape (by value) Move sum Constructor Shape (by value) Destructor Shape Value a is (1) Value b is (3) Value res is (4) Destructor Shape Destructor Shape Destructor Shape

Is it the good idea to mark copy constructor and copy operator= as "deleted" or I can remove those lines? How expensive std::move operator is by himself?


Solution

  • Is it the good idea to mark copy constructor and copy operator= as "deleted" or I can remove those lines?

    You can remove your deletes of the copy constructor and copy operator lines:

    https://en.cppreference.com/w/cpp/language/copy_constructor in Deleted implicitly-declared 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).

    How expensive std::move operator is by himself?

    std::move is used to cast a value to an xvalue (eXpiring value). It has no cost (it is cast at compile time) and the implications are that once you've called std::move on an object, you shouldn't use it after. For example, in your code, a+b gets implicitly cast to an xvalue

    You can find more info on xvalues here: https://en.cppreference.com/w/cpp/language/value_category