アフィリエイト広告を利用しています

広告

この広告は30日以上更新がないブログに表示されております。
新規記事の投稿を行うことで、非表示にすることが可能です。
posted by fanblog

2017年12月18日

《その187》 仮想関数,多相的クラス(前々回《185》の参考資料のみ)


 前回《186》、参考資料を追加したついでに、m(_ _)m さらにあと一つだけ追加させてください。
前々回《185》のプログラムコードの、
  関数 void print(Aaa& x);
  関数 int main();
を次のコードに入れ替えると、前々回《185》のプログラムでは仮引数 x が参照でしたが、x がポインタであっても同じだということを確認していただけると思います。

// ------------------------------------
void print(Aaa* x) {
x->statement();
cout << typeid(*x).name() << '\n';
}

int main() {
Aaa obj_a;
Bbb obj_b;
Ccc obj_c;

print(&obj_a);
print(&obj_b);
print(&obj_c);
}
// ------------------------------------

結果は、前々回《185》と同じなので、省略します。


新版 明解C 入門編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:13時点)

新版 明解C 中級編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:14時点)





《その186》 仮想関数,多相的クラス(前回《185》の参考資料のみ)


 今回は、前回《185》の説明の参考資料になるのではないかと思い、出力結果の比較を載せます。

 これは、前回《185》の結果です。
f05_0004.png


 下は、前回《185》のプログラムのコードから、赤文字の "virtual" を取り除いた場合の結果です。
f05_0005.png


 結果が異なる理由は、前回に書いたので、今回は省略します。



新版 明解C 入門編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:13時点)

新版 明解C 中級編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:14時点)





《その185》 仮想関数,多相的クラス


 仮想関数

 まず、今回のプログラムの概略です。
 基底クラス Base と、Base の public派生クラス Der1, Der2 があります。それぞれのクラスのメンバ関数 statement は仮想関数("virtual"が付加されている,関数名が同じ,仮引数が同じ)です。

 main関数では、
  Base型のオブジェクト bas
  Der1型のオブジェクト de1
  Der2型のオブジェクト de2
を作成し、各オブジェクトを引数にして、関数 print を呼び出します。関数 print は、それらのオブジェクトへの参照を受け取ります。

 関数 print(Base& x); は、Base&型の仮引数で各オブジェクトへの参照を受け取ります。
そして、受け取った参照先オブジェクトの動的な型に応じた仮想関数 statement が呼び出されることになります。
  bas の動的な型は Base型なので、呼び出されるのは Base::statement()
  de1 の動的な型は Der1型なので、呼び出されるのは Der1::statement()
  de2 の動的な型は Der2型なので、呼び出されるのは Der2::statement()
となります。

 また、関数 print(Base& x); は、
各オブジェクトの型を、typeid演算子を用いて出力します。
typeid演算子が返す型については、下記の多相的クラスの項目をご覧ください。


 多相的クラス

 仮想関数を含むクラスは、多相的クラスと呼ばれる特殊なクラスです。
  クラス Base は、仮想関数 statement を持っている
  クラス Der1 は、仮想関数 statement を持っている
  クラス Der2 は、仮想関数 statement を持っている
ので、すべて多相的クラスということになります。
多相的クラスであるため、関数 print(Base& x); の仮引数 x の参照先の型は、動的な型であると解釈されます。
typeid演算子は、その動的な型を返却します。


 下記のプログラムの出力結果は、次のようになります。
f05_0004070.png


 また、もし、各クラスの virtual print(Base& x); から virtual を取り除いて、仮想関数ではない状態にした場合の、出力結果は、次のようになります。
f05_0004080.png


// ------------------------------------
#include <typeinfo>
#include <iostream>
using namespace std;

class Base {
int a;
public:
Base(int x = 10) : a(x) { }
int get_a() const { return a; }

// 仮想関数
virtual void statement() const {
cout << "基底クラス Base\n";
}
};

class Der1 : public Base {
int b;
public:
Der1(int x = 20, int y = 22)
: Base(x), b(y) { }
int get_b() const { return b; }

// 派生クラスの "virtual" は省略可能です。
virtual void statement() const {
cout << "派生クラス Der1\n";
}
};

class Der2 : public Base {
int c;
public:
Der2(int x = 30, int y = 33)
: Base(x), c(y) { }
int get_c() const { return c; }

// 派生クラスの "virtual" は省略可能です。
virtual void statement() const {
cout << "派生クラス Der2\n";
}
};

void print(Base& x) {
x.statement();
cout << typeid(x).name() << '\n';
}

int main() {
Base bas;
Der1 de1;
Der2 de2;

print(bas); cout << '\n';
print(de1); cout << '\n';
print(de2);
}
// ------------------------------------





新版 明解C 入門編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:13時点)

新版 明解C 中級編 (明解シリーズ)

新品価格
¥2,916から
(2017/11/10 13:14時点)






 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


検索
<< 2017年12月 >>
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31            
プロフィール
こうすけさんの画像
こうすけ

 たまに、クリック お願いします m(_ _)m

 AA にほんブログ村 IT技術ブログ C/C++へ

こうすけ:メール kousuke_cpp@outlook.jp

【1】★★C++ 記事目次★★ ← 利用可能です。
・新版明解C++入門編 / 新版明解C++中級編
・その他 C++ 関連記事

【2】★★こうすけ@C#★★
・C# の初歩的な記事


×

この広告は30日以上新しい記事の更新がないブログに表示されております。