为什么当类具有引用成员时C++编译器不删除复制构造函数

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

本文关键字:编译器 C++ 删除 构造函数 复制 成员 引用 为什么      更新时间:2023-10-16

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

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

提供默认复制构造函数的任何原因?

#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;
}
可以在

复制构造函数中初始化引用,以引用与另一个类实例中的引用相同的对象。但是一旦初始化,就不能重新分配引用以引用不同的对象;因此,赋值运算符无法维护类似于复制构造函数的语义。


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

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

因为引用是可复制的。

如果提供了默认的复制赋值运算符,则源对象和目标对象的引用成员都引用同一副本。

不。无法提供隐式复制赋值运算符,因为无法为引用指定引用另一个对象。