2

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

程序启动时,会创建一个来自D类的对象 d,并调用D类的测试方法。该方法依次调用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;
}

更新:代码确实有效,问题与提供的代码无关,似乎来自提供 A、B、C 类的库与提供 D 类的库之间的版本不匹配。

4

3 回答 3

2

你确定它只打印“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)();
    }
};
于 2013-03-20T20:45:20.617 回答
0

它打印

IN B
IN C
IN D

所以,问题出在其他地方。

于 2013-03-20T20:43:05.733 回答
0

有用。添加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();
    }
};

输出:

IN B
IN C
IN D

于 2013-03-20T20:54:29.753 回答