使用成员函数指针调用正确的虚方法

calling the correct virtual method using member function pointer

本文关键字:方法 调用 成员 函数 指针      更新时间:2023-10-16

在下面的例子中,我试图将问题减少到最小,有4个类A,B,C,D。,形成继承层次

程序启动时,从类 d 创建一个对象d,并调用 d 类的test方法。该方法依次调用C类的调用者方法。该方法尝试使用成员函数指针调用正确的f方法。在这种情况下,它应该调用与类D相关联的f方法,但它调用与类B相关联的方法。

为什么?

class A {
    public:
    virtual void f() = 0;
};
class B : public A{
    public:
    virtual void f() { cout << "IN B" << endl;}   
};
class C : public B{
    public:
    virtual void f() { B::f(); cout << "IN C" << endl; }
    virtual void caller(){
        void (A::*cb)() = NULL;
        cb = &A::f;
        (this->*cb)();
    }
};
class D : public C{
    public:
    virtual void f() { C::f(); cout << "IN D" << endl; }
    void test(){
         caller();
    }
};
int main(){
    D d;
    d.test(); // Why does this prints only "IN B" 
    return 0;
}

UPDATE:代码实际工作,问题与所提供的代码无关,似乎来自提供类a,B,C的库与提供类d的库之间的版本不匹配

你确定它只打印"IN B"?我在MSVC2012上编译它,得到

IN B
IN C
IN D

更重要的是,你的原始代码不能在VS2012上编译,至少在我将public:添加到每个类之前。例如:

class C : public B{
public:  // <--- here
    virtual void f() { B::f(); cout << "IN C" << endl; }
    virtual void caller(){
        void (A::*cb)() = NULL;
        cb = &A::f;
        (this->*cb)();
    }
};

打印

IN B
IN C
IN D

所以,问题在别处

可以。添加public:声明。同时警告重载和虚拟化的不同行为。最好的方法是使用指针或引用。

class A {
public:
    virtual void f() = 0;
};
class B : public A{
    public:
    virtual void f() { std::cout << "IN B" << std::endl;}   
};
class C : public B{
    public:
    virtual void f() { B::f(); std::cout << "IN C" << std::endl; }
    virtual void caller(){
        void (A::*cb)() = NULL;
        cb = &A::f;
        (this->*cb)();
    }
};
class D : public C{
    public:
    virtual void f() { C::f(); std::cout << "IN D" << std::endl; }
    void test(){
         caller();
    }
};
输出:

B
在C
在D