请考虑以下代码。
#include <iostream>
#include <memory>
struct A {
A() {}
virtual void f() {
std::cout << "A::f" << std::endl;
}
private:
A(const A&);
};
struct B : public A {
virtual void f() {
std::cout << "B::f" << std::endl;
call(&A::f);
}
private:
void call(void (A::*aMethod)()) {
// ...
(static_cast<A&>(*this).*aMethod)();
//(static_cast<A>(*this).*aMethod)(); -> not allowed to copy!
// ...
}
};
void main() {
std::auto_ptr<B> b (new B);
b->f();
}
此代码递归调用相同的B::f
方法,直到它用完堆栈,而我希望call
方法调用A::f
。也就是说,它应该静态地调用它,就像我刚写的那样:
struct B : public A {
virtual void f() {
std::cout << "B::f" << std::endl;
// ...
A::f();
// ...
}
};
我希望拥有call
方法的原因是在“静态调用”之前和之后考虑一些代码,这些代码对于具有与f
相同签名的几个方法是通用的...
如何静态调用在运行时决定的虚函数?
答案 0 :(得分:5)
这是预期的。对象表达式是对基类A的引用,因此在A :: f为虚拟时触发虚函数机制(动态绑定)。
只有::运算符可以超越虚函数调用机制。
$ 10.3 / 12-“明确资格 范围运算符(5.1)抑制 虚拟呼叫机制。“
答案 1 :(得分:1)
当你拿指针时你的覆盖被解决了,所以你想要的就是这种方式。你可以做的最好的事情是一个调用你的函数的包装器 - 外部的东西,或者调用你的函数的非虚函数。如果你有C ++ 0x功能,你可以使用lambda,它是最干净的解决方案IMO。
你可能想重新考虑你做前/后功能的方式,作为解决问题的另一种方法:可以通过重载“ - &gt;”来实现它们。操作