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
Setting Vector Elements in Range-Based for Loop
Equivalent C++ to Python Generator Pattern
Generate Sha Hash in C++ Using Openssl Library
C++: When (And How) Are C++ Global Static Constructors Called
Empirically Determine Value Category of C++11 Expression
Do I Have to Use #Include <String> Beside <Iostream>
Expansion with Variadic Templates
Disallowing Creation of the Temporary Objects
Undefined Behaviour Somewhere in Boost::Spirit::Qi::Phrase_Parse
C++ - Decimal to Binary Converting
Boost.Asio-Based Http Client Library (Like Libcurl)
Math to Convert Seconds Since 1970 into Date and Vice Versa
Reading Line from Text File and Putting the Strings into a Vector
How to Test a String for Letters Only