使用成员函数指针调用正确的虚方法
calling the correct virtual method using member function pointer
在下面的例子中,我试图将问题减少到最小,有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
相关文章:
- 如何强制从重写方法调用重写的方法基方法?
- C++:使用方法调用析构函数的顺序是什么?
- 派生类调用父类的方法,该方法调用重写的虚拟方法调用错误的方法
- 使用 object 中的方法调用带有 std::bind 和 std::function.target 的 C 样式函数
- 指向类方法调用的指针
- 如何使用 SFINAE 在方法调用中有条件地定义变量?
- 是否有可以处理方法调用依赖关系的设计模式?
- 如何缩短C++中的方法调用?
- 从部分专用模板方法调用模板非静态方法
- 有没有办法禁止派生类中的基类方法调用?
- 为什么这C++只在编译器上编码一个不明确的方法调用Microsoft?
- 从父方法调用子方法
- 如何将子方法调用到父方法
- 虚拟函数在哪里使用 vpointer to vtable 来解析方法调用,非虚拟方法存储在哪里以及如何解析它们?
- 从静态方法调用静态函数指针
- 从同一类中的另一个方法调用方法时出错
- 方法调用意外地像 l 值一样起作用
- 无法从派生的一个方法调用基类方法
- 从类方法调用命名空间中名为 Same 的函数时,重载解析失败
- C 多线程JAVA JNI方法调用