Why C++ copy constructor must use const object?

本秂侑毒 提交于 2019-11-27 18:36:05
  • 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

The last thing any consumer of your class would expect is a copy constructor that changed the object that was copied! Therefore, you should always mark as const.

There are two reasons that const may be needed here:

  1. It ensures that you don't accidentally "damage" the original when making the copy - this is a good thing, because you don't really want your original object to be changed when making a copy of it!
  2. You can pass in something other than a basic object - since the constructor takes a reference, if it's not an object itself - say for example an expression.

To exemplify the second case:

 class ABC
    {
       public:
           int a;
           int b;
       ABC(const ABC &other)
       { 
         a = other.a;
         b = other.b;
       }
       ABC operator+(const ABC &other)
       {
           ABC res;
           res.a = a + other.a;
           res.b = b + other.b;
           return res;
       }
    }

  ...
  ABC A;
  a.a = 1;
  a.b = 2;
  ABC B(a+a);

This won't compile if the constructor is ABC(ABC &other), since a+a is a temporary object of type ABC. But if it's ABC(const ABC &other), we can use the temporary result of a calculation and still pass it in as a reference.

Andrew Lazarus

As several other answers point out, a copy constructor that modified its argument would be an unpleasant surprise. That is not, however, the only problem. Copy constructors are sometimes used with arguments that are temporaries. (Example: return from function.) And non-const references to temporaries don't fly, as explained elsewhere on SO.

If the copy constructor doesn't specify it's parameter as const then this fragment would not compile.

const ABC foo;
ABC bar(foo);

Copy constructors should not modify the object it is copying from which is why the const is preferred on the other parameter. Both will work, but the const is preferred because it clearly states that the object passed in should not be modified by the function.

const is for the user only. It doesn't exist for the actual executable.

Balog Pal

It's not a "must" in technical sense. We even have such beast right in the standard, though it got deprecated. Follow the links for the reasoning.

The semantics of copy we expect is to leave the "template" unchanged and provide a clone that is an exact equivalent in all regards, that you have hard time to tell form original.

That being expected you shall think twice to have a copy ctor that does otherwise. It will surprise users and likely introduce bugs. And frustration and noise, just try to google for 'vector of auto_ptr' just to see the count.

The remainder of the question could be "I swear not to touch the original in implementation, but want a different signature". What signature then? Let's try T and T&.

T drops out as it would require copy ctor to be usable and we're implementing just that. Recursion: see recursion.

That leaves T&. That would actually work for a deal of cases. But just fail if your original object happens to sit around in a const form, or be temporary. Why hinder that sensible case for no rain at all?

In addition to the fundamental assumption that copy constructors should not modify the source instance, this article elaborates on the actual technical reason for using const:

http://www.geeksforgeeks.org/copy-constructor-argument-const/

Namely that and I quote:

"... compiler created temporary objects cannot be bound to non-const references ..."

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!