What about self-construction in C++: should copy and move constructors handle calls with `*this` correctly?

138 Views Asked by At

What are best practices in C++ when the copy/move constructors are called with the object itself?

For example:

#include <iostream>

using namespace std;

struct Foo{
    Foo( const Foo& foo ) { cout << foo.val << std::endl; };
    int val;
};

int main()
{
    Foo f = Foo(f);
    Foo g(g);
    Foo h{h};
    return 0;
}

This is all legal C++, though some compilers will warn you about it.

It is commonly advised that copy assignment operators check for self-assignment. But what about self-copy construction?

1

There are 1 best solutions below

0
Brian Bi On

A copy constructor for T creates a new object whose value is the same as that of an existing object (the argument for the copy constructor). If you pass the object to its own copy constructor, it doesn't have a value yet, so there's no value to copy.

This can therefore be viewed as calling the copy constructor "out of contract", a bit like if the argument to the copy constructor were an object that had already been destroyed. It's not a valid call, so you don't need to check for this case in the implementation—unlike the situation with a self-copy-assignment, where x = x; is a valid call, so you do need to make sure it works properly.

If it were common for users to accidentally pass an object to its own constructor, there might perhaps be value in having a purely defensive check in the implementation, but code like Foo g(g); is highly unlikely to be written.

It is even less likely that someone will attempt to move-construct an object from itself.