使用基类函数指针访问派生类成员函数

Saq*_*ain 3 c++ visual-studio-2005 visual-c++

我在我的项目中使用函数指针,面临问题,创建了一个测试用例来显示它...下面的代码失败,MSVC2005上面有以下错误(简单来说我想通过基类函数指针访问dervied类函数)

错误C2440:'=':无法从'void(__ thiscall ClassB ::*)(void)'转换为'ClassAFoo'

class ClassA {
 public: 
    virtual void foo() 
    {
       printf("Foo Parent"); 
    }
};

typedef void (ClassA::*ClassAFoo)();

class ClassB : public ClassA {
 public:
    virtual void foo() 
    { 
        printf("Foo Derived"); 
    }
};

int main() {
    ClassAFoo fPtr;
    fPtr = &ClassB::foo;
}
Run Code Online (Sandbox Code Playgroud)

我的问题是

  1. 是不是C++行为,我无法通过基类函数指针或其编译器错误访问派生类函数?
  2. 我一直在玩上面的情况,如果我注释掉ClassB::foo,这段代码编译好了,没有任何进一步的修改,为什么这样,不应该fPtr = &ClassB::foo;再次导致编译时错误?

Rei*_*ica 5

  1. 这是正确的行为.可以这样想:ClassB拥有该成员的ClassA::foo所有实例,但不是所有ClassA拥有该成员的实例ClassB::foo; 只有那些实例ClassA实际上是实例的基类子对象ClassB才有它.因此,分配ClassB::foo到"纯" 对象ClassAFoo并随后ClassAFoo与"纯" ClassA对象结合使用将尝试调用不存在的函数.

  2. 如果你foo从中删除ClassB,那么表达式实际上是ClassB::fooClassA::foo继承的表达式ClassB,所以那里没有问题.

详细说明1.指向成员的指针实际上与普通指针的工作方式相反.与正常的指针,你可以分配ClassB*ClassA*(因为所有实例ClassB也的实例ClassA),而不是相反.随着成员的指针,你可以分配ClassA::*ClassB::*(因为ClassB包含的所有成员ClassA),而不是相反.