基本クラス メソッドのアドレスを保持できるポインター型があるとします。サブクラス メソッドのアドレスを割り当てて、正しく動作することを期待できますか? 私の場合、基本クラスのポインターで使用しており、オブジェクトの動的型は派生クラスです。
struct B
{
typedef void (B::*MethodPtr)();
};
struct D: public B
{
void foo() { cout<<"foo"<<endl; }
};
int main(int argc, char* argv[])
{
D d;
B* pb = &d;
//is the following ok, or undefined behavior?
B::MethodPtr mp = static_cast<B::MethodPtr>(&D::foo);
(pb->*mp)();
}
static_cast について話すとき、標準は次のように述べています。
5.2.9.9タイプ「タイプ cv1 T の D のメンバーへのポインター」の右辺値は、タイプ「タイプ cv2 T の B のメンバーへのポインター」の右辺値に変換できます。ここで、B は D の基底クラス (節 10) です。 「T 型の B のメンバーへのポインター」から「T 型の D のメンバーへのポインター」への有効な標準変換が存在し (4.11)、cv2 が cv1 と同じ cv-qualification、または cv1 より大きい cv-qualification である。63) null メンバ ポインタ値 (4.11) は、目的の型の null メンバ ポインタ値に変換されます。クラス B が元のメンバーを含む場合、または元のメンバーを含むクラスの基本クラスまたは派生クラスである場合、メンバーへの結果のポインターは元のメンバーを指します。それ以外の場合、キャストの結果は未定義です。[注: クラス B は元のメンバーを含む必要はありませんが、メンバーへのポインターが逆参照されるオブジェクトの動的型には、元のメンバーが含まれている必要があります。5.5 参照]
いつものように、私は基準を解読するのにとても苦労しています。大丈夫だと言っていますが、上記のテキストが私のコード例の状況に本当に当てはまるかどうかは100%確信が持てません.