C ++理解复制构造函数

时间:2017-10-16 20:53:32

标签: c++

有一些我无法理解的东西。看看这种主要的:

class C {
 public:
  C() { cout << "C0 "; }
  C(const C&) { cout << "Cc"; }
};

class D {
 public:
  C c;
  D() { cout << "D0 "; }
  D(const D&) { cout << "Dd"; }
};

int main() {

  D x; cout << endl;
  D y(x); cout << endl;
  return 0;

}

//output is:
C0 D0
C0 Dd

我同意D x给出C0 D0作为输出的事实,因为在D类中调用C的默认构造函数然后对象D是创建。

同样D y(x)就像D y = x,其中(像之前一样)创建了C(因此输出C0)并调用了复制构造函数。为什么Cc出现?如果你考虑这个代码:

class C {
 public:
  C() { cout << "C0 "; }
  C(const C&) { cout << "Cc"; }
};

class D {
 public:
  C c;
  D() { cout << "D0 "; }
};

int main() {

  D x; cout << endl;
  D y(x); cout << endl;
  return 0;

}

//output is:
C0 D0
Cc

为什么现在输出为Cc

代码是相同的,除了在D上没有复制构造函数的定义这样的事实。说D y(x)就像D y = x我希望在那之前就像C一样已创建(调用默认构造函数,因此输出C0),然后没有文本,因为D(const D&) 已定义。

也许我误解了复制构造函数。在这种情况下他们怎么称呼?

3 个答案:

答案 0 :(得分:6)

在第一种情况下,D Copy构造函数需要显式调用C拷贝构造函数。

D(const D &d) :  c(d.c) 
{ cout << "Dd"; }

在第二种情况下,由于您没有定义D copy-ctor,编译器会为您生成一个。

为了更清楚,请在C和D上添加一个额外的int。

static int counter;
class C {
 public:
  int index;
  C() { index = ++counter; cout << "C0 "; }
  C(const C&) { index = c.counter; cout << "Cc"; }
};

class D {
 public:
  int dcounter;
  C c;
  D() { dcounter = ++counter; cout << "D0 "; }
  D(const D&) : dcounter(D.dcounter)
{ cout << "Dd"; }
};

现在,使用调试器逐步执行,或添加更多printfs()。 当你做D y(x)时,你会看到y中的成员c没有被复制 - 只是构造了。

答案 1 :(得分:3)

定义自定义复制构造函数时,它会执行您告诉它的操作;你没有告诉它复制c成员,所以它没有,因此C0。实际上,如果您使用c中的某个值,那么您在新复制的成员中看不到它。

如果您没有自定义复制构造函数,则调用的默认构件将为其复制的成员调用复制构造函数。在这种情况下,您会在复制的实例中看到一个值结束。

答案 2 :(得分:3)

  

同样\'就像D y(x)

它不像它,它是完全正确的。后者只是第一个语法糖。

  

其中(像之前一样)D y = x被创建(所以输出C)并且复制构造函数被称为

不,在这种情况下不会调用C0复制构造函数。您没有定义C复制构造函数来调用D复制构造函数,因此C成员是默认构造的,这就是您看到c的原因,但是您实际上没有复制C0,但是您没有看到c

您希望Cc复制构造函数自动调用D成员的副本构造函数,但事实并非如此。您必须自己明确定义该行为,例如:

D
  

为什么D(const D &src) : c(src.c) { } 没有出现?

因为Cc示例中根本没有调用C副本构造函数。