ルック:ここメンバー関数ポインタは、関数が実際に宣言したクラスに基づいた型を持つのはなぜですか?このスニペットで
struct A {
void fn();
};
struct B: A {
};
void f() {
auto x = &B::fn;
}
、x
は私が&B::fn
を書いたという事実にもかかわらず、void (A::*)()
の種類を取得します。
fn
をB
に追加した場合、x
のタイプはvoid (B::*)()
となります。
したがって、タイプ&B::fn
は、Bがfn
であるかどうかを変更します。
この現象の背景には何がありますか?私はそれが驚くべきことだと思う。
なぜこの点が重要ですか?たとえば、プログラマXが私の例のようにA
とB
を作成するとします。プログラマYは&B::fn
を使い、その型のクラス部分を何か(テンプレートのパラメータなど)に使用します。プログラマーXは、fn
にいくつかの追加機能が必要であると認識して、それを上書きします。さて、タイプ&B::fn
が変更されたので、プログラマのYのコードが壊れる可能性があります。
'fn'がオーバーライドされると、クラスインタフェースが変更されます。プログラマーYは再コンパイルする必要があり、タイプは再び正しくなります。 – patatahooligan
これは一貫した動作のようです。プログラマーYのコードは 'fn'が削除されたり名前が変更されたりすると壊れるでしょう。 – VTT
@VTT:はい、通常は関数のオーバーライドを追加しても何も破られません。関数を削除/名前変更すると、コンパイル時にエラーが発生することが予想されます。オーバーライドを追加するときは無効です。 – geza