Move semantics of a method chained to a constructor

  c++, constructor, move-semantics

I am new to C++ and am trying to get a grip on move semantics. The following code is a barebones struct I wrote. It is not the best example of software engineering by any means, but it is just for learning purposes. It owns a resource, has the copy constructor and copy assignment operator deleted, has a move constructor and a move assignment operator defined, has a destructor, and has a single method that is supposed to return the original object:

struct HasAResource
{
    int* arr;

    HasAResource(int size):
        arr(new int [size])
    {}

    HasAResource(const HasAResource& other) = delete;
    HasAResource& operator=(const HasAResource& other) = delete;

    HasAResource(HasAResource&& other):
        arr(nullptr)
    {
        arr = other.arr;
        other.arr = nullptr;
    }

    HasAResource& operator=(HasAResource&& other)
    {
        if (this != &other)
        {
            delete[] arr;
            arr = other.arr;
            other.arr = nullptr;
        }
        return *this;
    }

    ~HasAResource() { delete[] arr; }

    HasAResource& doStuff()
    {
        return *this;
    }
};

int main(int argc, char const *argv[])
{
    HasAResource x = HasAResource(42).doStuff();
    return 0;
}

In the main function, I attempted to construct an object and call the method on it immediately. My goal was to modify the temporary object I constructed and them move it to x without making any copies (so that there is only one owner of the resource). However, the compiler gives me an error related to the deleted copy constructor. This means that it is trying to make a copy despite my best efforts.

My questions are:

  1. What exactly is happening here? Where is the new object an rvalue or an lvalue and why?
  2. How can I modify this program to achieve the desired behavior, if it is possible?

Once again, my goal is to understand what the language is doing, not the best software engineering practices (like using std::unique_ptr).

Source: Windows Questions C++

LEAVE A COMMENT