【问题标题】:Why copy constructor needs to be const? [duplicate]为什么复制构造函数需要是 const? [复制]
【发布时间】:2017-03-26 04:55:03
【问题描述】:

我有一个关于复制构造函数的问题,假设一个 class A 包含一个 int,具有默认构造函数、复制构造函数 (?) 和接收 int 的构造函数

class A {
  int value;
public:
  A(): value(0) {}                  // Default
  A(A& copy): value(copy.value) {}  // Copy (?)
  A(const int n): value(n) {}       // Receives an int for 'value'

  int get_value() { return value; } // Return value
};

还有一个包含A pointer 的类,名为BoxForA

class BoxForA {
  A *obj;
public:
  BoxForA(): obj(nullptr) {}
  BoxForA(const int a) { obj = new A(a); }

  A popf(){ return *obj; }  // Returns the content of obj_A (an A element)
};

还有主要的(将打印三个3):

int main() {
  A a(3);
  A b = a;  // Calling copy constructor for b (this works with non-const parameter)

  BoxForA box1(3);
  A c = box1.popf();  // Calling copy constructor for c (this doesn't work with non-const parameter)

  cout << "a = " << a.get_value() << endl;
  cout << "b = " << b.get_value() << endl;
  cout << "c = " << c.get_value() << endl;
  return 0;
}

当我编译这个时,编译器给了我这个错误:

error: invalid initialization of non-const reference of type ‘A&’ from an rvalue of type ‘A’
   A c = box1.popf();
                  ^

就这样,我认为我的复制构造函数需要 const 参数,而不是非常量,所以像这样编辑我的复制构造函数:

A(const A& obj): value(obj.value) {}

我的程序现在编译没有错误并显示以下输出:

a = 3
b = 3
c = 3

不错!我找到了解决方案 :D .... 不,因为我不知道它为什么有效。

你能告诉我为什么会这样吗?为什么复制构造函数似乎有const参数?

【问题讨论】:

  • box1.popf() 返回一个临时值 - 它只能“绑定”到 const 引用。
  • 如果你说它必须保持不变,那么不。如果你问是否应该,那么是的。 cpy ctor 引用同一类的对象并将其值复制到新的 being created 并且只要它不更改 rhs 值,那么根据经验法则,我们将其传递给 const 引用

标签: c++ c++11 constructor


【解决方案1】:

当你写作时

A c = box1.popf();

它调用复制构造函数,如你所知:

A c(box1.popf()); // copy constructor

现在,popf 返回什么?它返回一个A,一个prvalue(基本上是一个右值——C++11 中存在差异)。但是等等,复制构造函数采用&amp;,它只绑定到左值,因此您的代码无法编译。

但是当你添加const时,签名现在是const&amp;,它接受右值和左值,并且代码编译。

如果你写,你会遇到完全相同的问题:

int& a = 1; // 1 is a prvalue, but a only accepts lvalues

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-15
    • 2013-11-23
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 2018-08-06
    相关资源
    最近更新 更多