«

»

11月
05

C++に予約語superがない理由

c++を参考(反面教師?)にして作られたJavaでは、
派生クラスの関数から継承元の基底クラスへの関数への参照を行う際superという予約語を使う。
例えば次のようなコード。

public class A  {
   public void handle(void){}
}
public class B extends A {
   public void handle(void){ super.handle(); }
}

c++を使っていると時々この便利な予約語がなぜなかったのだろう?とか考えてしまいます。
少し考えると、Javaでは多重継承が認められない一方で、それが可能なC++では
コンパイルエラーにせざるを得ない局面があることに気づきます。

struct A { virtual void handle(void); };
struct B { virtual void handle(void); };
struct C : A,B { void handle(void); };
 
void C::handle(void)
{
   A::handle();               //問題ない
   inherited::handle();   //CはAとBから派生しているため曖昧になるのでエラーとなる。
}

この為、予約語でないのだと私は勝手に解釈していました。
ただ多重継承を使わない限り有効な表記法なので、実際Visual C++には独自拡張として__superなる予約語があります。

ではなぜ標準にはないのか?

この理由が面白い。
C++標準化の際、極力無駄な予約語を増やさないという1つの指標がありました。
ただ、先に存在していた言語Smalltalkにはsuperなる同様の用途のものがあり実績もあった為、C++にも導入する動きがあったそうです。
その是非の際、一人の賢者が以下のような代替コードを提示した事により、最終的に導入が却下されたそうです。

class foreman : public employee {
   typedef employee inherited;
   void print();
};
 
class manager : public foreman {
   typedef foreman inherited;
   void print();
};
 
void manager::print()
{
   inherited::print();
}
この経緯は、C++の生みの親であるBjarne Stroustrup著の「C++の設計と進化」という本に書かれています。
私たちが見過ごしていたのは、ネステッドクラスをC++に導入した事によって、タイプ名のスコープと解決を、ほかの名前とまったく同様に制御する可能性が生まれていたことだ。
つまりわざわざ予約語を1個増やさなくてもtypedefのスコープを利用すれば同様な事が実現できるので不用であるという結論だったという事です。

この本には言語の誕生から標準化に至るまでの意見交換や本人の意志が垣間見えて面白いです。
Bjarne先生はとっても人間臭い感じがして、いい人っぽい印象ですw

コメントを残す

メールアドレスは公開されません

次の HTMLタグおよび属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>