在下面的示例中,我尝试将问题简化为最小值,有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;
}
UPDATE :代码实际上有效,问题与所提供的代码没有任何关系,似乎来自提供类A,B,C和提供类的库之间的版本不匹配D.
答案 0 :(得分:2)
你确定它只打印“IN B”吗?我在MSVC2012上编译它,我得到了
IN B
IN C
IN D
更重要的是,你的原始代码不能在VS2012上编译,至少在我向每个类添加public
之前都没有编译。 e.g:
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)();
}
};
答案 1 :(得分:0)
打印
IN B
IN C
IN D
所以,问题出在其他地方。
答案 2 :(得分: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