Foo f1;
Foo f2(f1);
はい、これは期待どおり
の動作をします: f2 コピー コンストラクター Foo::Foo(Foo const&) が呼び出されます。
このコピーは、その基本クラスを構築し、次に各メンバーを (再帰的に) 構築します
次のようなクラスを定義する場合:
class X: public Y
{
private:
int m_a;
char* m_b;
Z m_c;
};
次のメソッドは、コンパイラによって定義されます。
- コンストラクター (デフォルト) (2 つのバージョン)
- コンストラクター (コピー)
- デストラクタ (デフォルト)
- 代入演算子
コンストラクタ: デフォルト:
実際には 2 つのデフォルト コンストラクターがあります。
1 つは に使用されzero-initialization
、もう 1 つは に使用されvalue-initialization
ます。()
使用されるは、初期化中に使用するかどうかによって異なります。
// Zero-Initialization compiler generated constructor
X::X()
:Y() // Calls the base constructor
// If this is compiler generated use
// the `Zero-Initialization version'
,m_a(0) // Default construction of basic PODS zeros them
,m_b(0) //
m_c() // Calls the default constructor of Z
// If this is compiler generated use
// the `Zero-Initialization version'
{
}
// Value-Initialization compiler generated constructor
X::X()
:Y() // Calls the base constructor
// If this is compiler generated use
// the `Value-Initialization version'
//,m_a() // Default construction of basic PODS does nothing
//,m_b() // The values are un-initialized.
m_c() // Calls the default constructor of Z
// If this is compiler generated use
// the `Value-Initialization version'
{
}
注: 基本クラスまたはいずれかのメンバーに、有効な表示可能な既定のコンストラクターがない場合、既定のコンストラクターを生成できません。コードがデフォルトのコンストラクターを使用しようとしない限り、これはエラーではありません (コンパイル時エラーのみ)。
コンストラクター (コピー)
X::X(X const& copy)
:Y(copy) // Calls the base copy constructor
,m_a(copy.m_a) // Calls each members copy constructor
,m_b(copy.m_b)
,m_c(copy.m_c)
{}
注: 基本クラスまたはいずれかのメンバーに有効な可視コピー コンストラクターがない場合、コピー コンストラクターは生成できません。コードがコピー コンストラクターを使用しようとしない限り、これはエラーではありません (コンパイル時エラーのみ)。
代入演算子
X& operator=(X const& copy)
{
Y::operator=(copy); // Calls the base assignment operator
m_a = copy.m_a; // Calls each members assignment operator
m_b = copy.m_b;
m_c = copy.m_c;
return *this;
}
注: 基本クラスまたはいずれかのメンバーに有効な実行可能な代入演算子がない場合、代入演算子は生成できません。コードで代入演算子を使用しようとしない限り、これはエラーではありません (コンパイル時エラーのみ)。
デストラクタ
X::~X()
{
// First runs the destructor code
}
// This is psudo code.
// But the equiv of this code happens in every destructor
m_c.~Z(); // Calls the destructor for each member
// m_b // PODs and pointers destructors do nothing
// m_a
~Y(); // Call the base class destructor
- コンストラクター (コピーを含む) が宣言されている場合、既定のコンストラクターはコンパイラーによって実装されません。
- コピー コンストラクターが宣言されている場合、コンパイラはそれを生成しません。
- 代入演算子が宣言されている場合、コンパイラは代入演算子を生成しません。
- デストラクタが宣言されている場合、コンパイラはデストラクタを生成しません。
コードを見ると、次のコピー コンストラクターが生成されます。
Foo::Foo(Foo const& copy)
:bar(copy.bar)
{}
Bar::Bar(Bar const& copy)
:i(copy.i)
,baz(copy.baz)
{}
Baz::Baz(Baz const& copy)
:j(copy.j)
{}