コピーコンストラクション関数と付与オペレータの継承への応用
3033 ワード
継承では、コピーコンストラクタと付与オペレータの表現の特性が異なります.
コピーコンストラクション関数は、コンストラクションとコピーの二重の責任を負い、いずれの場合もベースクラス部分を構築する必要があります.付与オペレータは異なり、すでに構築されたオブジェクトをターゲットにし、付与するだけでいいです.
派生クラスのコンストラクタなしおよび代入オペレータシーン:
例では、派生クラスにはベースクラスのオブジェクトも含まれています.結果は次のとおりです.
派生クラスコピーコンストラクタと付与オペレータが空の場合、ベースクラスとメンバーオブジェクトのコンストラクタと付与オペレータが自動的に呼び出されます.
派生クラスコンストラクタと割り当てオペレータの不完全なシーン:
コピーコンストラクション関数は、ベースクラスとメンバーオブジェクトのデフォルトコンストラクション関数を呼び出します.コピーコンストラクション関数は呼び出されません.付与オペレータは、派生クラス自体の関数に限定されます.
派生クラス完全コンストラクタおよび代入オペレータシーン:
上記の状況に基づいて、完全な書き方は以下の通りです.
コピーコンストラクション関数は、コンストラクションとコピーの二重の責任を負い、いずれの場合もベースクラス部分を構築する必要があります.付与オペレータは異なり、すでに構築されたオブジェクトをターゲットにし、付与するだけでいいです.
派生クラスのコンストラクタなしおよび代入オペレータシーン:
#include
using namespace std;
class B {
public:
B()
{
cout << "B()" << endl;
}
B(const B&b) {
cout << "B" << endl;
}
B& operator=(const B &b) {
cout << "B=" << endl;
return *this;
}
};
class D: public B{
public:
D()
{
cout << "D()" << endl;
}
private:
B b;
};
int main()
{
D d1;
cout << "----------------
";
D d2 = d1;
cout << "----------------
";
d2 = d1;
return 0;
}
のサンプルコードは、上記のように動作します.B()
B()
D()
----------------
B
B
----------------
B=
B=
. . .
例では、派生クラスにはベースクラスのオブジェクトも含まれています.結果は次のとおりです.
派生クラスコピーコンストラクタと付与オペレータが空の場合、ベースクラスとメンバーオブジェクトのコンストラクタと付与オペレータが自動的に呼び出されます.
派生クラスコンストラクタと割り当てオペレータの不完全なシーン:
#include
using namespace std;
class B {
public:
B()
{
cout << "B()" << endl;
}
B(const B&b) {
cout << "B" << endl;
}
B& operator=(const B &b) {
cout << "B=" << endl;
return *this;
}
};
class D: public B{
public:
D()
{
cout << "D()" << endl;
}
D(const D&d){
cout << "D" << endl;
}
D& operator=(const D &d) {
cout << "D=" << endl;
return *this;
}
private:
B b;
};
int main()
{
D d1;
cout << "----------------
";
D d2 = d1;
cout << "----------------
";
d2 = d1;
return 0;
}
のサンプルコードは、上記のように動作します.B()
B()
D()
----------------
B()
B()
D
----------------
D=
. . .
結果により、コピーコンストラクション関数は、ベースクラスとメンバーオブジェクトのデフォルトコンストラクション関数を呼び出します.コピーコンストラクション関数は呼び出されません.付与オペレータは、派生クラス自体の関数に限定されます.
派生クラス完全コンストラクタおよび代入オペレータシーン:
上記の状況に基づいて、完全な書き方は以下の通りです.
#include
using namespace std;
class B {
public:
B()
{
cout << "B()" << endl;
}
B(const B&b) {
cout << "B" << endl;
}
B& operator=(const B &b) {
cout << "B=" << endl;
return *this;
}
};
class D: public B{
public:
D()
{
cout << "D()" << endl;
}
D(const D&d):B(d), b(d){
cout << "D" << endl;
}
D& operator=(const D &d) {
B::operator =(d);
b = d.b;
cout << "D=" << endl;
return *this;
}
private:
B b;
};
int main()
{
D d1;
cout << "----------------
";
D d2 = d1;
cout << "----------------
";
d2 = d1;
return 0;
}
結果:B()
B()
D()
----------------
B
B
D
----------------
B=
B=
D=
. . .
は、第1のケースと比較して、ベースクラスおよびメンバー関数のコピー関数および付与オペレータを呼び出した上で、派生クラス関数の処理方法を追加する.