有一些我无法理解的东西。看看这种主要的:
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&)
未已定义。
也许我误解了复制构造函数。在这种情况下他们怎么称呼?
答案 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
副本构造函数。