次はコンストラクタと継承について書きたいと思います。
まずは、コンストラクタ関数を持ったクラスを継承した時の動きを確認してみましょう。
<sample program cpp077-01>
#include <iostream> class Base { public: Base(); }; class Derived : public Base { public: Derived(); }; int main() { Derived derived; return 0; } Base::Base() { std::cout << "基底クラスのコンストラクタ関数" << std::endl; } Derived::Derived() { std::cout << "派生クラスのコンストラクタ関数" << std::endl; } |
<実行結果>
基底クラスのコンストラクタ関数 派生クラスのコンストラクタ関数 続行するには何かキーを押してください・・・
「派生クラス」が実体をもった時に、「基底クラス」のコンストラクタ関数が呼び出され、次に「派生クラス」のコンストラクタ関数が呼ばれています。
では「基底クラス」のコンストラクタ関数に引数を設定してみます。
<sample program cpp077-02>
#include <iostream> class Base { public: Base(const int value); void ShowValue() const; protected: int m_value; }; class Derived : public Base { public: Derived(); }; int main() { Derived derived; derived.ShowValue(); return 0; } Base::Base(const int value) : m_value(value) { std::cout << "基底クラスのコンストラクタ関数" << std::endl; } void Base::ShowValue() const { std::cout << "m_value = " << m_value << std::endl; } Derived::Derived() { std::cout << "派生クラスのコンストラクタ関数" << std::endl; } |
<コンパイル結果>
error C2512: 'Base': クラス、構造体、共用体に既定のコンストラクターがありません。 note: 'Base' の宣言を確認してください
「基底クラス」には引数を受け取るコンストラクタ関数しか用意されていません。
引数の無い「既定のコンストラクタ」は作られないので、引数を渡さなければクラスの実体は作れません。
しかし、「基底クラス」の実体は直接作られているのでは無く、「派生クラス」の中で作られています。
「派生クラス」から「基底クラス」のコンストラクタ関数に引数を渡すには↓のようにします。
<sample program cpp077-03>
#include <iostream>
class Base {
public:
Base(const int value);
void ShowValue() const;
protected:
int m_value;
};
class Derived : public Base {
public:
Derived();
};
int main()
{
Derived derived;
derived.ShowValue();
return 0;
}
Base::Base(const int value) : m_value(value)
{
std::cout << "基底クラスのコンストラクタ関数" << std::endl;
}
void Base::ShowValue() const
{
std::cout << "m_value = " << m_value << std::endl;
}
Derived::Derived() : Base(12)
{
std::cout << "派生クラスのコンストラクタ関数" << std::endl;
}
|
<実行結果>
基底クラスのコンストラクタ関数 派生クラスのコンストラクタ関数 m_value = 12 続行するには何かキーを押してください・・・
「派生クラス」のコンストラクタ関数の初期化リストで「基底クラス」のコンストラクタ関数への引数を渡します。
もちろん、「派生クラス」のコンストラクタ関数も引数を受け取る事が可能です。
「派生クラス」で受け取った引数を「基底クラス」に渡す事も出来ます。
<sample program cpp077-04>
#include <iostream> class Base { public: Base(const int value); void ShowValue() const; protected: int m_value; }; class Derived : public Base { public: Derived(const int value); }; int main() { Derived derived(35); derived.ShowValue(); return 0; } Base::Base(const int value) : m_value(value) { std::cout << "基底クラスのコンストラクタ関数" << std::endl; } void Base::ShowValue() const { std::cout << "m_value = " << m_value << std::endl; } Derived::Derived(const int value) : Base(value) { std::cout << "派生クラスのコンストラクタ関数" << std::endl; } |
<実行結果>
基底クラスのコンストラクタ関数 派生クラスのコンストラクタ関数 m_value = 35 続行するには何かキーを押してください・・・