読者です 読者をやめる 読者になる 読者になる

C++でinheritedキーワードを使う

c/c++

嘘嘘、inheritedキーワードなんてないよ。
ただ、C++に入りそうで入らなかったinheritedキーワードは実在する。
inheritedキーワードというのは、
Javaのsuperみたいなもの。

これに関したバグがこないだあったので、考慮しないととか感じたり。
例えば、継承関係でこんな感じのがあったとして、

Unit - Human
   Elf
   Dwarf

Unitクラスが肥大化してきたため、
人間系、であるクラスを挟み込みたいと感じたとする。

Unit - Humanoid - Human
         Elf
         Dwarf

このとき、
Humanの実装に、
Unit::execute();
なんていう記述があると、
これはスーパークラスの実装を呼び出すことを意図しているのだが、
Humanoidが挿入され、Humanoidに適切なexecuteがあった場合も問題なくビルドが通り、
Humanoid::executeは実行されないようになってしまう。

これを防ぐために、
super::execute();
なんて書ければ良いのだが、生憎C++では「多重継承による曖昧性を持ち込まれるため」superキーワードがない。
ただ、C++の仕様策定の段階ではinheritedキーワードとしてこれらの機能が盛り込まれるかもしれなかったという歴史がある。
(D&E P.370参照のこと)

D&Eによる曖昧の説明はこう。

struct A { virtual void handle(int); };
struct B { virtual void handle(int); };
struct D : A, B { virtual void handle(int); };

void D:handle(int i)
{
    A::handle(i);    // 曖昧でない
    inherited::handle(i); // 曖昧
}

要するに直系のsuperが定まらないことによる問題。
故に、inheritedキーワードは問題になり、
これらの多重継承が持ち込まれたときだけ曖昧性を持ち込むようにする?という話があがった。
しかし、

class foreman : public employee {
    typedef employee inherited;
    // ...
    void print();
};

class manager : public foreman {
    typedef foreman inherited;
    // ...
    void print();
};

void manager::print()
{
    inherited::print();
    // ...
}

で、typedefすればできるよねーということで、この拡張は入らないことになった。
ということで、inheritedがバグを緩和させるか仕事のコードに適応適用して実践してみることにする。