基本クラス(次の例では:clA
)が、ルーチンexecutor
から呼び出される関数ポインタを定義する、いくつかのクラス階層を作成しました。次に、コールバックとしてexecutor
が渡されたコードは、それが動作する派生オブジェクトのタイプを知らない(clB
はそのうちの1つだけです)。派生クラスがいくつかの関数を実装していない場合、それは関数ポインタにキャストされず、executor
が呼び出されると何も起こりません。いくつかの仮想機能もあります(clA
は実際には純粋な仮想です)。私classessは次のようになり(実際のコードを提示することはできませんので、私は単純化されたデモを作成):バーチャル性を持つマルチレベル階層は、キャスト関数ポインタを防止する
class clA
{
protected:
INT_PTR(__stdcall clA::*Fn1)(int);
INT_PTR(__stdcall clA::*Fn2)(int);
static INT_PTR CALLBACK executor(UINT operation, int opData, clA *ptr = NULL)
{
switch (operation)
{
case 1:
if (ptr->Fn1)
{
typedef INT_PTR(__stdcall clA::*FPtr)(int);
FPtr funcPtr = ptr->Fn1;
return (ptr->*funcPtr)(opData);
}
break;
case 2:
if (ptr->Fn2)
{
typedef INT_PTR(__stdcall clA::*FPtr)(int);
FPtr funcPtr = ptr->Fn2;
return (ptr->*funcPtr)(opData);
}
break;
}
}
public:
clA() { Fn1 = NULL; Fn2 = NULL; }
virtual BOOL vrt(void) = 0;
};
class clB : public clA
{
INT_PTR __stdcall ImplFn1(int) { return 0; }
INT_PTR __stdcall ImplFn2(int) { return 0; }
public:
void testing(void);
clB()
{
Fn1 = reinterpret_cast <INT_PTR(__stdcall clA::*)(int)> (&clB::ImplFn1);
Fn2 = reinterpret_cast <INT_PTR(__stdcall clA::*)(int)> (&clB::ImplFn2);
}
BOOL vrt(void) { return FALSE; };
};
すべてが今まで働いていた、私は、基本クラスclA
が他のクラスから継承するために必要なことを決めただけで、今日、それはclExtra
も聞かせて、私は変更以下の作っ:今、私は以下のコンパイルエラーが発生している
class clExtra
{
public:
static int x;
};
//now class clA is deriving from clExtra
class clA : public clExtra
問題
を:
inheritancetest.h(49): error C2440: 'reinterpret_cast' : cannot convert from 'INT_PTR (__stdcall clB::*)(int)' to 'INT_PTR (__stdcall clA::*)(int)'
Pointers to members have different representations; cannot cast between them
私は正直、彼らが突然異なる表現になっているかを理解していません。 C2440の可能性のあるMSDNの例は適用されません。奇妙なことは、もし私がclA
クラスから仮想性を取り除くと、私はそれをコンパイルすることができるということです。誰かがキャストできない原因を理解できれば、私はいつも説明に感謝します。
実際には、すべてのキャストを 'static_cast'に置き換えることができましたが、私はそれを避けたかったのです。それらの数が非常に多いからです... 1000コンストラクタを再検証するよりも、しかし、バグ。私はそれに着くでしょう、一方、似たような経験を持つ他の人がこの投稿を読んでいます – Kitet
@Kitetなぜ 'static_cast'を使いたくないのですか?パフォーマンス?私はこの場合、追加の指示は必要ないので挿入されないと思う。生成されたアセンブリを100%確認したい場合は、 – PcAF
あなたは何か誤解をしているに違いありません。私は静的にそれらのすべてを切り替え、すべてのコンストラクタといくつかのテストのために2時間かかりました。 – Kitet