1

C++ compiler will not provide default copy assignment operator to a class which has reference member(and some other scenarios also). Reason is, if default copy assignment operator is provided then both source and destination object's reference member refers to same copy.

However, default copy constructor is provided in same scenario and this introduces same problem as providing default copy assignment operator.

Any reason for providing default copy constructor?

#include <iostream>
using namespace std;

class People{
public:
    People(string name = ""):m_name(name){
}
string getName(){
    return m_name;
}
void setName(string name){
    m_name = name;
}
private:
    string& m_name;//reference member
};

int main() {
    People a("Erik");
    People b(a);
    a.setName("Tom");
    cout << a.getName() << endl;//This prints "Tom"
    cout << b.getName() << endl;//This prints "Tom"
    //a = b; //Build error
    return 0;
}
  • 2
    Undefined behavior will do possibly surprising things. – Eljay Jun 18 '19 at 14:26
  • 3
    Note - you are taking the constructor's parameter *by value* and then saving a reference to it. That's undefined behaviour if you use that reference. – Fureeish Jun 18 '19 at 14:26
  • 1
    "_If default copy assignment operator is provided then both source and destination object's reference member refers to same copy_" I'm sorry I don't understand that sentence. – curiousguy Jun 18 '19 at 14:27
  • This line: `m_name = name;` is undefined behavior should it ever execute. That's because `m_name` is a reference to an object that has been destroyed. The way your code is written shows that you have a significant misunderstanding regarding what references are and how they work. – Omnifarious Jun 18 '19 at 14:34
  • @Omnifarious technically, is it really UB if you never use that reference? – Fureeish Jun 18 '19 at 14:42
  • @Fureeish - Note the line of code I mentioned. That line is using the reference. And I added the qualifier _should it ever execute_. So yes, you're right. It isn't if you never use the reference. But I accounted for that in my comment. :-) – Omnifarious Jun 18 '19 at 14:47

2 Answers2

4

A reference can be initialized, in the copy constructor, to refer to the same object as the reference in the other class instance. But once initialized, the reference cannot be reassigned to refer to a different object; so an assignment operator cannot maintain semantics similar to those of a copy constructor.


Your example binds m_name reference to the constructor's parameter, which goes out of scope when the constructor returns, leaving the reference dangling. Any use of m_name afterwards exhibits undefined behavior. You shouldn't be reaching any conclusions based on the behavior of this program.

Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85
0

Why C++ compiler does not delete copy constructor when class has reference member?

Because references are copyable.

If default copy assignment operator is provided then both source and destination object's reference member refers to same copy.

No. Implicit copy assignment operator cannot be provided because references cannot be assigned to refer to another object.

eerorika
  • 232,697
  • 12
  • 197
  • 326