Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do move constructors and move assignment operators make sense in classes that don't hold pointers as member variables and don't manage resources?

Tags:

c++

In the articles and books I have read so far, there are only move operations done in classes that hold pointers. Those operations fundamentally work by swapping pointers and setting the old pointers to nullptr. But what happens when std::move() is called on a class without any pointers using the default assignment operator? Example:

#include <iostream>

class MyClass
{
public:
    MyClass(int x) : x(x) {}
    int x = 0;
    MyClass& operator=(MyClass&& other) = default;
};

int main()
{
    MyClass a{ 10 };
    MyClass b{ 20 };

    std::cout << a.x << '\n';
    a = std::move(b);
    std::cout << a.x << '\n';
}

Result is

10
20

It seems to have worked, but how? Did it do anything different from a normal assignment operator?

like image 948
Cool_Cornflakes Avatar asked Nov 18 '25 01:11

Cool_Cornflakes


1 Answers

An explicit move constructor or a move operator can be specified for any class, whether it has pointer members or not. It is true that move constructors and operators are usually used with classes that have pointers of some kind. But that's only because in these cases there's a way to effect a move that avoids the more expensive overhead of copying.

A default move operation for a trivial type is equivalent to a copy operation.

A default move operation for a class is equivalent to a move operation for each member of the class.

Therefore, in your example, the move operation is equivalent to a copy operation, and has no observable differences.

However it is certainly possible to need a move operator for a class that has no pointer members, for whatever reason. A classical example is std::thread, which has a move constructor and an assignment operator but not the equivalent copy constructor and copy assignment operator. The contents of std::thread are implementation defined, but typically consist of an opaque handle for an operating system-specific thread identifier. This handle cannot be "copied" in any meaningful way, but its ownership can be meaningful transferred to another std::thread, and that's why you have move operators there.

Your own classes may have similar semantical requirements, too, even if they don't have any pointers of any kind.

like image 105
Sam Varshavchik Avatar answered Nov 20 '25 15:11

Sam Varshavchik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!