2017年12月10日
《その171》 継承とデフォルトコンストラクタ & p.159演習4-1
継承とデフォルトコンストラクタ
派生クラスにおいてコンストラクタが定義されていない場合は、コンパイラによって自動でデフォルトコンストラクタが定義されます。その際、『その派生クラスの直接基底クラスが"引数を与えることなく呼び出せるデフォルトコンストラクタ"をもっていなければ、コンパイルエラーとなります。』
次の 演習4-1 は、そのことを確認するための問題です。
新版明解C++中級編 p.159 演習4-1
下記のプログラムで、クラス Base のコンストラクタを、次の二通り @, Aのコンストラクタに置きかえたプログラムを作成して、下の【重要事項】の内容を確認せよ。
@ Base::Base(int xx)
: x(xx) { cout << "Base::x を " << x << " で初期化。\n"; }
A Base::Base(int xx = 99)
: x(xx) { cout << "Base::x を " << x << " で初期化。\n"; }
【重要事項】コンストラクタを定義しないクラスは、そのクラスの直接基底クラスが"引数を与えることなく呼び出せるデフォルトコンストラクタ"をもっていなければ、コンパイルエラーとなる。
// ------------------------------------
#include <iostream>
using namespace std;
class Base {
int x;
public:
Base() : x(99) { cout << "Base::x を 99 で初期化。\n"; }
// ↑のコンストラクタを書きかえること。
int get_x() const { return x; }
};
class Derived : public Base {
};
int main()
{
Derived d;
cout << "d.get_x() = " << d.get_x() << '\n';
}
// *** 実行結果 ******************
// * Base::x を 99 で初期化。 *
// * d.get_x() = 99 *
// *******************************
// ------------
◆以下が解答になります。
元々のコード
Base() : x(99) { cout << "Base::xを99で初期化。\n"; }
の場合、基底クラス Base は"引数を与えることなく呼び出せるデフォルトコンストラクタ"をもっているので、コンパイルは成功します。
@のコード
Base::Base(int xx)
: x(xx) { cout << "Base::x を " << x << " で初期化。\n"; }
の場合、基底クラス Base は"引数を与えることなく呼び出せるデフォルトコンストラクタ"をもっていないので、コンパイルエラーになります。
Aのコード
Base::Base(int xx = 99)
: x(xx) { cout << "Base::x を " << x << " で初期化。\n"; }
の場合、基底クラス Base は"引数を与えることなく呼び出せるデフォルトコンストラクタ"をもっているので、コンパイルは成功します。
以下は、Aの場合のプログラムと、その実行結果です。
// p159_演習4-1
#include <iostream>
using namespace std;
class Base {
int x;
public:
Base::Base(int xx = 99) : x(xx) {
cout << "Base::x を " << x << " で初期化。\n";
}
int get_x() const { return x; }
};
class Derived : public Base {
};
int main()
{
Derived d;
cout << "d.get_x() = " << d.get_x() << '\n';
}
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/7075163
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック