如果类有引用数据成员,为什么默认赋值运算符不由编译器合成 在C++中,如果一个类有一个引用数据成员,则默认赋值操作符不是由编译器合成的。为什么?

如果类有引用数据成员,为什么默认赋值运算符不由编译器合成 在C++中,如果一个类有一个引用数据成员,则默认赋值操作符不是由编译器合成的。为什么?,c++,C++,在会员论坛上观看了讨论。由于大多数程序员都不知道这个答案,所以我想在这里发布答案并与大家分享 从C++标准草案N33 37→12·823: 如果X具有以下情况,则类X的默认复制/移动分配运算符定义为已删除: 具有非平凡对应赋值运算符的变量成员,X是 工会式的阶级,或 常量非类类型(或其数组)的非静态数据成员,或 引用类型的非静态数据成员,或 类类型为M(或其数组)的非静态数据成员,不能 复制/移动,因为过载分辨率(13.3),适用于M的相应 赋值运算符,导致歧义或函数被删除或删除 无法从默认的

在会员论坛上观看了讨论。由于大多数程序员都不知道这个答案,所以我想在这里发布答案并与大家分享

<>从C++标准草案N33 37→12·823:

如果X具有以下情况,则类X的默认复制/移动分配运算符定义为已删除:

  • 具有非平凡对应赋值运算符的变量成员,X是 工会式的阶级,或
  • 常量非类类型(或其数组)的非静态数据成员,或
  • 引用类型的非静态数据成员,或
  • 类类型为M(或其数组)的非静态数据成员,不能 复制/移动,因为过载分辨率(13.3),适用于M的相应 赋值运算符,导致歧义或函数被删除或删除 无法从默认的赋值运算符访问,或
  • 由于过载而无法复制/移动的直接或虚拟基类B 决议(13.3),适用于B的相应赋值运算符,导致 从默认值中删除或无法访问的歧义或函数 赋值运算符,或
  • 对于移动赋值运算符,为非静态数据成员或直接基类 使用一个没有移动赋值运算符且不平凡的类型 可复制的,或任何直接或间接的虚拟基类
<>强> C++中,如果一个类有一个引用数据成员,默认赋值操作符不是由编译器合成的。为什么?

副本分配应执行的操作定义如下:

C++03标准12.8/13:

每个子对象都以适合其类型的方式指定:

  • 如果子对象是类类型,则使用该类的复制赋值运算符(如同通过显式限定;即忽略更多派生类中任何可能的虚拟重写函数)

  • 如果子对象是数组,则以适合元素类型的方式指定每个元素

  • 如果子对象是标量类型,则使用内置赋值运算符

简而言之,它意味着每个成员都应该以适当的方式分配
这就提出了一个问题,
类中引用成员的赋值行为应该是什么?
参考下面的参考文献:

  • 引用本质上是不可赋值的,它们不断引用初始化时所引用的同一个引用[Ref 1]
  • 由于
    #1
    分配给引用不会重新分配引用,它会更改引用的值,这是一种非直观行为
  • 这里没有执行默认的正确行为,而是一个相当的情况。因此C++标准规定,类的设计者处于最佳位置来确定这种行为,因此,如果一个类有一个引用数据成员,则默认赋值操作符不应该由编译器合成。 此决定在中指定:
    C++03标准12.8/12:

    当为其类类型的对象分配了其类类型的值或从其类类型派生的类类型的值时,将隐式定义隐式声明的复制赋值运算符。如果隐式定义了复制赋值运算符的类有:
    ,则程序的格式不正确 ....
    -引用类型的非静态数据成员,或


    [参考文献1]
    C++03标准8.5.3/2:

    初始化后,无法将引用更改为引用另一个对象。请注意,对引用的初始化的处理与对其赋值的处理非常不同。参数传递(5.2.2)和函数值返回(6.6.3)都是初始化


    该引用将被初始化为什么?无法重新分配引用。简单地赋值会修改被引用对象,这可能不是您想要的。您发布了一个来自标准的引用,这很好,但更重要的是要理解原因:赋值运算符必须为LHS对象的引用成员赋值一个新值,但不能重新赋值引用(它们是隐式常量)。