In fact, the copy constructor should, imho, always accept a const reference as an argument.
X(X& rhs) { } // does not modify rhs
This does not allow const objects to be copied and, therefore, the following code will not compile. Although objects that are not constants can serve as arguments to const, it is impossible to avoid another way.
X const test; X new_x(test);
I cannot imagine why anyone should exclude a copy of the const object.
Regarding the changes you want to make: Is the copy constructor relying on any X-member function that is not defined by const?
This will work like a charm, but allow copying const objects:
class X { private: int a; public: X(X &rhs) { a = rhs.value(); } int& value (void) { return a; } };
The following example will not compile since rhs is const, but value() not const.
class X { private: int a; public: X(X const &rhs) { a = rhs.value(); } int& value (void) { return a; } };
If you want your const class to be correct, you probably have to examine the whole class. This should only affect the implementation within the class. Since I do not know the case when external code must rely on the "non-constant" function of a member of the class. Unless non-const links are returned by any public member functions, as in my example.
The following snippet will work as intended.
class X { private: int a; public: X(int const &b) : a(b) { } X(X const &rhs) { a = rhs.value(); } int const & value (void) const { return a; } };
But keep in mind that this will affect any code:
X test(100); test.value() = 12;
This will work using int& value (void) { return a; } int& value (void) { return a; } , but not with int const & value (void) const { return a; } int const & value (void) const { return a; } . Of course, you could both be safe.