2016-10-16 4 views
2

基本クラス(次の例では: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クラスから仮想性を取り除くと、私はそれをコンパイルすることができるということです。誰かがキャストできない原因を理解できれば、私はいつも説明に感謝します。

答えて

1

私はそれがVC++のバグだと思います。それはgccでcompiles successfullyです。

static_castは、このタイプの変換には十分です。

reinterpret_castの代わりにstatic_castを使用した場合、VC++は文句を言わないことを発見しました。

+0

実際には、すべてのキャストを 'static_cast'に置き換えることができましたが、私はそれを避けたかったのです。それらの数が非常に多いからです... 1000コンストラクタを再検証するよりも、しかし、バグ。私はそれに着くでしょう、一方、似たような経験を持つ他の人がこの投稿を読んでいます – Kitet

+0

@Kitetなぜ 'static_cast'を使いたくないのですか?パフォーマンス?私はこの場合、追加の指示は必要ないので挿入されないと思う。生成されたアセンブリを100%確認したい場合は、 – PcAF

+0

あなたは何か誤解をしているに違いありません。私は静的にそれらのすべてを切り替え、すべてのコンストラクタといくつかのテストのために2時間かかりました。 – Kitet

関連する問題