通过函数指针静态调用虚函数

时间:2010-12-03 13:02:57

标签: c++ static virtual

请考虑以下代码。

#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相同签名的几个方法是通用的...

如何静态调用在运行时决定的虚函数?

2 个答案:

答案 0 :(得分:5)

这是预期的。对象表达式是对基类A的引用,因此在A :: f为虚拟时触发虚函数机制(动态绑定)。

只有::运算符可以超越虚函数调用机制。

  

$ 10.3 / 12-“明确资格   范围运算符(5.1)抑制   虚拟呼叫机制。“

答案 1 :(得分:1)

当你拿指针时你的覆盖被解决了,所以你想要的就是这种方式。你可以做的最好的事情是一个调用你的函数的包装器 - 外部的东西,或者调用你的函数的非虚函数。如果你有C ++ 0x功能,你可以使用lambda,它是最干净的解决方案IMO。

你可能想重新考虑你做前/后功能的方式,作为解决问题的另一种方法:可以通过重载“ - &gt;”来实现它们。操作