具有虚拟性的多级层次结构可防止转换函数指针

时间:2016-10-16 18:40:34

标签: c++ casting member-function-pointers

我已经创建了一些类层次结构,其中基类(在下面的示例中为clA)定义了从executor例程调用的函数指针。反过来,作为回调传递executor的代码不知道它运行的是哪种类型的派生对象(clB只是其中之一)。如果派生类没有实现某些函数,它就不会转换为函数指针,并且在调用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

老实说,我不明白他们是如何突然变成不同的陈述。 MSDN的可能C2440原因示例不适用。奇怪的是,如果我从clA类删除任何虚拟,我也可以编译它。如果有人理解可能导致我无法施展的原因,我将永远感激解释。

1 个答案:

答案 0 :(得分:1)

我认为这是VC ++中的错误。它是gcc中的compiles successfully

static_cast足以进行此类转化。

我发现使用static_cast代替reinterpret_cast时VC ++不会抱怨。