2chのC++相談室で、色々と議論が巻き起こっているようだ。少なくとも一人は、規格を参照しているようである。C++の規格上の、overloadとoverrideとhidingについて、分かりやすくまとめてみた。オーバーロードとオーバーライドは、単に音訳した際に、日本人にとって音が非常に似ているという問題に過ぎないのだが。
同じ名前で、他のシグネチャの違う関数セットのことを、関数のオーバーロード(overload)という。
void f(int) ; void f(double) ;
この例では、void f(int)とvoid f(double)は、オーバーロードされた関数のセットである。
Derived classがBase classと同じvirtual関数を宣言しているとき、Derived classのvirtual関数は、Base classの同virtual関数を、オーバーライド(override)しているという。
struct Base { virtual void f() {} } ; struct Derived : Base { virtual void f() {}// override } ;
Derived classのメンバー名に対し、同名のBase classのメンバーがある場合、Derived classのメンバーは、Base classのメンバーを隠している(hiding)という。
struct Base { void f(int) ; int value ; } ; struct Derived : Base { void f(double) ; double value ; } ; int main() { Derived d ; d.f(0) ; // void Derived::f(dobule)を呼ぶ d.value ; // double Derived::valueである }
結局これは、Derived classスコープのメンバーである名前が、Base classスコープのメンバーの名前を隠しているに過ぎない。同じことは、クラス以外のスコープでも起こる。
int value ; // グローバルスコープの変数 void f() {// 関数fのブロックスコープ int value ; // ::valueを隠す。 value ; // ローカル変数のvalue }
virtual関数はoverrideするものである。Derived classの非virtualなメンバー関数に対し、同名のBase classの非virtualなメンバー関数がある場合、それは単に、名前を隠しているだけである。
今執筆中のC++本では、これらの用語は正しく使うつもりだが、ことさらに用語を解説したりはしない。ただし、どうも「引数」という言葉は、parameter(仮引数)とargument(実引数)をそこまで厳密に区別しなくても、問題のない場合が多いので、単に引数とだけ書いている箇所が多数ある。最初は厳密に書き分けようとしたが、すぐに、意味のないことだと気がついた。そこまで厳密に知りたければ、最初から規格を読むべきなのだ。
No comments:
Post a Comment