Why is the copy-constructor argument const?
Asked Answered
L

8

33
 Vector(const Vector& other) // Copy constructor 
 {
    x = other.x;
    y = other.y;

Why is the argument a const?

Lait answered 21/10, 2009 at 16:42 Comment(4)
That should be Vector(const Vector& other) : x(other.x), y(other.y) {} Read about initialization lists and why they're good to use: stackoverflow.com/questions/1598967Chance
const-correctness is probably a term you want to look upIntolerable
Although it's const 99% of the time, there is a counter-example; see std::auto_ptr.Fleet
Of course auto_ptr is deprecated because even the experts at the standards committee didn't manage to get it completely right. Therefore I'd say if you find a non-const argument to a copy constructor, you can be fairly sure the code is broken.Eloign
D
62

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.

Downwards answered 21/10, 2009 at 16:58 Comment(4)
And not only temporary objects - it also allows the copy constructor to be used on named objects that happen to be marked const.Eboni
This is super confusing. Can you tell me the difference between "const Vector& other" and "Vector const &other"?Cortico
@HoyCheung: There is no difference between those.Downwards
@HoyCheung The "readable" way to put the const specifier is after the type you want to make const. For example: int cont * cont to create a constant pointer to constant integer (an inverse reading of the declarator matches the type you are defining), but the first const (if any) can be also placed before (const int * const), I think for some kind of compatibility with primitive versions of C, or simply for tradition.Cobnut
K
21

Because you are not going to modify the argument other inside the copy ctor as it is const.

When you did x = other.x it essentially means this->x = other.x. So you are modifying only this object just by copying the values from other variable. Since the other variable is read-only here, it is passed as a const-ref.

Kingdon answered 21/10, 2009 at 16:43 Comment(2)
It's considered "good defensive programming" by (a) telling the caller that they don't have to worry about changes to the argument being passed in and (b) telling the implementor that they are not allowed to change the argument.Jugendstil
It's also necessary because you want to be able to bind rvalues to the ctor's argument: X x = f();. This isn't possible with non-const references.Chance
M
3

The traditional copy-ctor and friends take a const& parameter for reasons specified above. However, you should also look up move-semantics and r-value references (to be part of C++0x, if all goes well) to see why and when you will use copy-ctors without a const& parameter. Another place to look at is the implementation of smart pointers such as auto_ptr (which have transfer of ownership semantics) where non-const parameters are useful.

Marquetry answered 21/10, 2009 at 18:44 Comment(0)
K
1

In order to not be able to change other (by accident)?

Kurt answered 21/10, 2009 at 16:44 Comment(0)
R
1

when we try to copy one object into another using copy constructor,we need to maintain the original copy of original object (which we are copying) so while passing object we make it constant and we pass it as a by reference.

Request answered 15/2, 2011 at 6:45 Comment(0)
D
0

The idea of a copy constructor is that you are copying the contents of the other object into the this object. The const is there to ensure that you don't modify the other object.

Dandelion answered 21/10, 2009 at 16:43 Comment(0)
P
0

Its not specific to copy constructor. In any function if you are not going to modify the internal state of the object then object will be passed as const.

Vector(const Vector& other) 
{
     //Since other is const, only public data member and public methods which are `const` can be accessed.
}
Polio answered 21/10, 2009 at 16:47 Comment(2)
Since Vector is a Vector, can't you can access private members of other?. If you replaced the Vector argument with OtherClass, you can't access private members.Thalassa
@jamuraa: You can access them, but you are not allowed to modify them. To attempt to is a compile-time error.Chance
M
0

It can also come handy if you want to copy an object you only have a const reference to for example

...
const Vector& getPosition();
...

Vector* v = new Vector(getPosition());

If it wasn't for Vector(const Vector& other) that example would create a syntax error.

Minotaur answered 21/10, 2009 at 18:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.