【问题标题】:why default copy-ctor is generated for a class with reference member variable?为什么为具有引用成员变量的类生成默认的 copy-ctor?
【发布时间】:2017-03-13 01:33:20
【问题描述】:

http://coliru.stacked-crooked.com/a/8356f09dff0c9308

#include <iostream>
struct A
{
  A(int& var) : r(var) {}
  int &r;
};

int main(int argc, char** argv)
{
    int x = 23;

    A a1(x);   // why this line is fine?

    A a2 = a1; // why this line is fine?

    a2 = a1; // error: use of deleted function 'A& A::operator=(const A&)'
            // note: 'A& A::operator=(const A&)' is implicitly deleted because the default definition would be ill-formed:
            // error: non-static reference member 'int& A::r', can't use default assignment operator
    return 0;
}

默认赋值运算符被删除。为什么仍然保留默认的复制构造函数?

【问题讨论】:

  • 因为引用可以被构造(初始化/绑定),但不能重新分配(反弹)。
  • @songyuanyao:请在回答区回答!

标签: c++ c++11


【解决方案1】:
A a1(x);

很好,因为它正在使用引用构造A 的实例(x 被转换为引用并调用构造函数A(int&amp;)

A a2 = a1;

也很好,因为它是仍然构造。事实上,复制结构。 可以用另一个引用来初始化一个引用。

例如:

int a = 1;
int& b = a;
int& c = b;

没关系,因为这都是建设性的 (Demo)

但是,您不能分配引用,这是a2 = a1 将尝试通过编译器生成的复制分配运算符执行的操作。但是,编译器认识到了这一点,并没有生成这样的运算符。由于该运算符不存在,因此您遇到了编译器错误。

【讨论】:

    【解决方案2】:

    分配和构造是两种不同的野兽。

    默认赋值运算符不能存在,因为引用不能被分配给(如果你尝试在“user-land”代码中,你实际上将分配给引用对象)。

    默认的复制构造函数没有这样的问题,因为我们可以创建引用就好了。

    【讨论】:

      【解决方案3】:

      复制赋值运算符和复制构造函数是两个不同的东西。它不保证复制赋值运算符存在时,复制构造函数也存在,但它们遵循自己的规则。

      来自copy assignment operator,它提到:
      如果 T 具有引用类型的非静态数据成员,则类 T 的默认复制赋值运算符定义为“已删除”。就是这样:D

      对于复制构造函数,它有自己的规则来决定是否删除,例如,如果一个类中存在非静态右值引用数据成员,那么默认的复制构造函数将被定义为'Deleted'。更多内容请访问docs

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-10-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-11-27
        • 1970-01-01
        相关资源
        最近更新 更多