Why Is the Copy-Constructor Argument Const

Why C++ copy constructor must use const object?

  • Logically, it should make no sense to modify an object of which you just want to make a copy, though sometimes it may have some sense, like a situation where you'd like to store the number of time this object has been copied. But this could work with a mutable member variable that stores this information, and can be modified even for a const object (and the second point will justify this approach)

  • You would like to be able to create copy of const objects. But if you're not passing your argument with a const qualifier, then you can't create copies of const objects...

  • You couldn't create copies from temporary reference, because temporary objects are rvalue, and can't be bound to reference to non-const. For a more detailed explanation, I suggest Herb Sutter's article on the matter

Why is the copy-constructor argument const?

You've gotten answers that mention ensuring that the ctor can't change what's being copied -- and they're right, putting the const there does have that effect.

More important, however, is that a temporary object cannot bind to a non-const reference. The copy ctor must take a reference to a const object to be able to make copies of temporary objects.

Why copy constructor needs to be const?

When you write

A c = box1.popf();

It calls the copy constructor, as you know:

A c(box1.popf()); // copy constructor

Now, what does popf return? It returns an A, a prvalue (basically an rvalue - there is a difference in C++11). But wait, the copy constructor takes a &, which only binds to lvalues, and so your code doesn't compile.

But when you add const, the signature is now const&, which accepts rvalues and lvalues, and the code compiles.

You get exactly the same problem if you write:

int& a = 1; // 1 is a prvalue, but a only accepts lvalues

Is Const important for Copy Constructor?

The copy constructor is traditionally declared as

Foo(const Foo&);

since it is assumed that a copy doesn't change the object on its right hand side (at least a good copier shouldn't change it, right?)

In standard C++, you cannot bind a temporary to a non-const reference. Visual Studio uses a non-standard extension, and that's why your code compiles, but you should not rely on non-standard extensions.

It is not absolutely necessary to have your copy constructor taking the rhs by const reference, it is also OK to take it by reference. But in that case, you won't be able to perform copy initialization from a rvalue (a temporary basically).

Why should the copy constructor accept its parameter by reference in C++?

Because if it's not by reference, it's by value. To do that you make a copy, and to do that you call the copy constructor. But to do that, we need to make a new value, so we call the copy constructor, and so on...

(You would have infinite recursion because "to make a copy, you need to make a copy".)



Related Topics



Leave a reply



Submit