2018年01月03日
《その218》 仮想派生
仮想派生の例 class A { ・・・・・・ }; class B : virtual public A { ・・・・・・ }; class C : virtual public A { ・・・・・・ }; class D : public B, public C { ・・・・・・ }; | ![]() |
非仮想派生の例 class A { ・・・・・・ }; class B : public A { ・・・・・・ }; class C : public A { ・・・・・・ }; class D : public B, public C{ ・・・・・・ }; | ![]() |
以下は、
class A { ・・・・・・ };
class B : virtual public A { ・・・・・・ };
class C : virtual public A { ・・・・・・ };
class D : public B, public C { ・・・・・・ };
のタイプの仮想派生を行うプログラム例です。
基底クラス A のメンバは、データメンバ int v と、そのゲッタ,セッタ(このセッタは値の読み出しもできます)です。
B のメンバは、A のデータメンバ v を読み出す関数のみ、
また、C のメンバは、A のデータメンバ v に値をセットする関数(この関数は値の読み出しもできます)のみです。
そして、D は、この B と C を多重継承します(D の中ではメンバの定義はありません)。
// ------------------------------------
#include <iostream>
class A {
int v;
protected:
int val() const { return v; }
int& val() { return v; }
// 関数 val のオーバーロード
// 戻り値の型だけで識別される関数は
// オーバーロードできないため、2つ
// の 関数 val の差は const の有無。
public:
A() : v(0) { }
// デフォルトコンストラクタは、v を 0 で
// 初期化します。
};
class B : virtual public A {
public:
int get() const { return val(); }
// 基底クラス A の
// 関数 int val() const { return v; }
// をゲッタとして利用します。
};
class C : virtual public A {
public:
int& set() { return val(); }
// 基底クラス A の
// 関数 int& val() { return v; }
// をセッタとして利用します。
};
class D : public B, public C { };
int main() {
D d;
// D型のクラスオブジェクト d を生成。
std::cout << d.get() << '\n';
d.set() = 100;
// 関数 set は、基底クラス A の関数
// int& set() { return val(); }
// を利用しているため、使い方が
// やや特殊です。
std::cout << d.get() << '\n';
d.set() = 999;
std::cout << d.get() << '\n';
}
// ------------------------------------

この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/7156098
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック