明示的に定義されたコピーコンストラクタは、そのメンバーのコピーコンストラクタを呼び出しません。
コンストラクタの本体を入力すると、そのクラスのすべてのメンバーが初期化されます。つまり、{
になると、すべてのメンバーが初期化されていることが保証されます。
指定されていない限り、メンバーはクラスに表示される順序でデフォルトで初期化されます。(そうできない場合、プログラムは不正です)。したがって、独自のコピーコンストラクタを定義すると、メンバーコピーコンストラクタを必要に応じて呼び出すことができます。これは印刷し、
#include <iostream>
class Foo {
public:
Foo() {
std::cout << "In Foo::Foo()" << std::endl;
}
Foo(const Foo& rhs) {
std::cout << "In Foo::Foo(const Foo&)" << std::endl;
}
};
class Bar {
public:
Bar() {
std::cout << "In Bar::Bar()" << std::endl;
}
Bar(const Bar& rhs) {
std::cout << "In Bar::Bar(const Bar&)" << std::endl;
}
};
class Baz {
public:
Foo foo;
Bar bar;
Baz() {
std::cout << "In Baz::Baz()" << std::endl;
}
Baz(const Baz& rhs) {
std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}
};
int main() {
Baz baz1;
std::cout << "Copying..." << std::endl;
Baz baz2(baz1);
}
として、次のとおりです:
In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
Copying...
In Foo::Foo()
In Bar::Bar()
In Baz::Baz(const Baz&)
注意を、それがデフォルト初期化のメンバーをだとここで
は、コピー&ペーストすることができますどこかと周りの混乱に小さなプログラムですBaz
。
のように、明示的なコピーコンストラクタをコメントアウトすることにより:
/*
Baz(const Baz& rhs) {
std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}
*/
出力は、このになります:
In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
Copying...
In Foo::Foo(const Foo&)
In Bar::Bar(const Bar&)
それは両方でコピーコンストラクタを呼び出します。
そして、我々はBaz
年代を再導入かのコンストラクタをコピーして、明示的に単一のメンバーをコピーします。
Baz(const Baz& rhs) :
foo(rhs.foo)
{
std::cout << "In Baz::Baz(const Baz&)" << std::endl;
}
我々が得る:
In Foo::Foo()
In Bar::Bar()
In Baz::Baz()
Copying...
In Foo::Foo(const Foo&)
In Bar::Bar()
In Baz::Baz(const Baz&)
をあなたが見ることができるように、明示的にコピーコンストラクタを宣言したら、 はすべてのクラスメンバーのコピーを担当します。それは今あなたのコンストラクタです。
これは、移動コンストラクタを含むすべてのコンストラクタに適用されます。
参照:http://stackoverflow.com/questions/563221/is-there-an-implicit-default-constructor-in-c/563320#563320 –