为什么 C++ 编译器在 class 有引用成员时不删除复制构造函数?

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

C++ 编译器不会为具有引用成员的 class(以及其他一些情况)提供默认的复制赋值运算符。 原因是,如果提供默认复制赋值运算符,则源对象和目标对象的引用成员都引用相同的副本。

但是,在同一场景中提供了默认复制构造函数,这会引入与提供默认复制赋值运算符相同的问题。

提供默认复制构造函数的原因是什么?

#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;
}

可以在复制构造函数中初始化引用,以引用与另一个 class 实例中的引用相同的对象。但是一旦初始化,引用就不能被重新分配以引用不同的对象;所以赋值运算符不能保持类似于复制构造函数的语义。


您的示例将 m_name 引用绑定到构造函数的参数,该参数在构造函数 returns 时超出范围,使引用悬空。之后对 m_name 的任何使用都会表现出未定义的行为。您不应根据此程序的行为得出任何结论。

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

因为引用是可复制的。

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

没有。无法提供隐式复制赋值运算符,因为无法将引用分配给另一个对象。