C++ で仮想継承2021年02月22日 12時13分27秒

仮想関数は C++ で良くお目に掛かる。virtual が付いた関数で、関数呼び出しの時に生成されたクラスを元に、動的に呼ぶ関数を選ぶ機構だ。あまり目に付かないが、仮想継承も存在する。

継承のクラスを書くときに virtual キーワードを使う。

class A: virtual public B
{
};
これは、いわゆるダイヤモンド型の継承を行うときに必要になる形。二つのクラスを継承するが、その二つのクラスも他の同一クラスを継承している場合。
class B: public A
{
};
class C: public A
{
};
上のクラス B と C はクラス A を基底としている。これの B と C をそのまま継承するとコンパイルエラーになる。

実際のコードを使っての実験。追加の継承を組んだが、clang は問題を見つけてくれる。

% cat virtual_inheritance.cpp 
struct A { ~A(){} };
struct B : public A { };
struct C : public A { };
struct D : public B { };
struct E : public B, public C { };

struct Z : virtual public A { };
struct Y : virtual public A { };
struct X : public Z, public Y { };

A* a() { return new A; }
A* b() { return new B; }
A* d() { return new D; }
A* e() { return new E; }
A* x() { return new X; }
X、Y、Z のクラスは仮想継承を使っているのでエラーにならない。
% clang++ virtual_inheritance.cpp 
virtual_inheritance.cpp:14:17: error: ambiguous conversion from derived class
      'E' to base class 'A':
    struct E -> struct B -> struct A
    struct E -> struct C -> struct A
A* e() { return new E; }
                ^~~~~
1 error generated.

コメント

コメントをどうぞ

※メールアドレスとURLの入力は必須ではありません。 入力されたメールアドレスは記事に反映されず、ブログの管理者のみが参照できます。

※なお、送られたコメントはブログの管理者が確認するまで公開されません。

名前:
メールアドレス:
URL:
コメント:

トラックバック

このエントリのトラックバックURL: http://uyota.asablo.jp/blog/2021/02/22/9349659/tb

※なお、送られたトラックバックはブログの管理者が確認するまで公開されません。