たったこれだけです。例題のプログラムを書いてみましょう。[手順] 1.継承元クラスで、オーバーライドされる関数を virtualとして宣言する(仮想関数といいます) 2.継承先クラスで、オーバーライドする関数を普通に宣言する
#include <iostream.h> class Moto { public: virtual int kaso(); }; class Saki : public Moto { public: int kaso(); }; int Moto::kaso(void) { cout << "継承元です" << endl; return 0; } int Saki::kaso(void) { cout << "オーバーライドしました" << endl; return 0; } int main(void) { Saki a; Moto b; a.kaso(); b.kaso(); return 0; }
たったこれだけのプログラムです。継承元のクラスで
基本になる関数をvirtual宣言しておいて継承先の
クラスで、この関数の機能を拡張して使うときなどに利用します。
さて、ここでクラスへのポインタについて考えてみます。
これも、
結果はどれも同じですね。
さて、ポインタを使ってメンバ関数を呼び出すときも
全く同じ要領です。
結果も予想通りと思います。ここで注意すべきことは、
MotoとかSakiとかいうのは、ユーザーが新しく定義した
データ型と考えることができます。
当然MotoとSakiは違うデータ型でしょう。
ところが、上のプログラムで
#include <iostream.h>
class Pointer
{
public:
int a;
Pointer();
~Pointer(){};
};
Pointer::Pointer(void)
{
a = 100;
}
int main(void)
{
Pointer x;
Pointer *ptr;
ptr = &x;
cout << "x.a は " << x.a << endl;
cout << "ptr->a は " << ptr->a << endl;
cout << "(*ptr).a は" << (*ptr).a << endl;
return 0;
}
#include <iostream.h>
class Moto
{
public:
virtual int kansu(void);
};
class Saki : public Moto
{
public:
int kansu(void);
};
int Moto::kansu(void)
{
cout << "元のクラスです" << endl;
return 0;
}
int Saki::kansu(void)
{
cout << "先のクラスです" << endl;
return 0;
}
int main(void)
{
Moto moto, *p_moto;
Saki saki, *p_saki;
p_moto = &moto;
p_saki = &saki;
(*p_moto).kansu();
(*p_saki).kansu();
p_moto->kansu();
p_saki->kansu();
return 0;
}
としても、コンパイラは注意してくれません。
このような使い方は間違いではありませんが
(それどころか大変便利な使い方があります)、
バグが発生すると大変わかりにくいです。
したがって初心者の方にはあまりお勧めできません。
p_moto = &saki;
[C++Index]
[総合Index]
[Previous Chapter]
[Next Chapter]
当ホーム・ページの一部または全部を無断で複写、複製、
転載あるいはコンピュータ等のファイルに保存することを禁じます。