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

发布于 2024-10-06 01:00:58 字数 1019 浏览 4 评论 0原文

请考虑以下代码。

#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 具有相同签名的多个方法...

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

Please consider the following code.

#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();
}

This code recursively calls the same B::f method until it runs out of stack, while I would like the call method to call A::f. That is, it should call it statically as it would normally happen had I simply written:

struct B : public A {
  virtual void f() {
    std::cout << "B::f" << std::endl;
    // ...
    A::f();
    // ...
  }
};

The reason I want to have the call method is to factor some code before and after the 'static call' that is common to several methods with the same signature as f...

How can I statically call a virtual function decided at run-time?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

眉黛浅 2024-10-13 01:00:58

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

只有::操作符可以抑制虚函数调用机制。

$10.3/12-“显式限定
作用域运算符 (5.1) 抑制
虚拟调用机制。”

That's expected. The object expression is a Reference to the Base class A and hence virtual function mechanism (dynamic binding) is triggered as A::f is virtual.

Only the :: operator can supperess virtual function call mechanism.

$10.3/12- "Explicit qualification with
the scope operator (5.1) suppresses
the virtual call mechanism."

仙女 2024-10-13 01:00:58

当您获取指针时,您的覆盖就会被解决,因此您在这里想要的东西通过这种方式并不容易实现。您能做的最好的事情就是调用您的函数的包装器 - 要么是外部函数,要么是调用您的函数的非虚拟函数。如果您有 C++0x 功能,您可以使用 lambda,这是我认为最干净的解决方案。

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

Your override is resolved when you take the pointer, so what you want here is not easily possible this way. The best thing you can do is a wrapper that calls your function - either something external, or a non-virtual function that calls your function. If you have C++0x features, you could use a lambda which is the cleanest solution IMO.

You might wanna rethink the way you do pre/post-functions as another way to tackle your problem: They can be implemented by overloading the "->" operator.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文