如何实现虚函数回调?

发布于 2025-01-08 01:32:35 字数 394 浏览 1 评论 0原文

我正在使用 wxWigets,但我想这个问题更多的是如何实现虚函数回调。这是我的代码的(非常)简化版本:

// MyGUI.h 
Class MyGUI : public wxFrame {

  ...
  protected:
     virtual void onFeedButton_cb( wxCommandEvent& event ) { event.Skip(); }
  ...
}

// Animal.h 
Class Animal {

  public: 
       void Feed(); 
}

一个简单的问题:如何实现 onFeedButton_cb 回调,以便它可以访问 Animal 的 Feed() 函数?即在运行时回调必须能够访问 Animal 的实例。

I am using wxWigets, but I suppose this question is more of how to implement callbacks that are virtual functions. This is a (very) simplified version of my code:

// MyGUI.h 
Class MyGUI : public wxFrame {

  ...
  protected:
     virtual void onFeedButton_cb( wxCommandEvent& event ) { event.Skip(); }
  ...
}

// Animal.h 
Class Animal {

  public: 
       void Feed(); 
}

A trivial question: How do I implement the onFeedButton_cb callback so that it can access Animal's Feed() function?? i.e. during run time the callback must have access to an instance of Animal.

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

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

发布评论

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

评论(3

女皇必胜 2025-01-15 01:32:35

定义一个为您调用该虚拟函数的非虚拟函数,并将该非虚拟函数附加到回调中。

#include <memory>
#include <iostream>

class Animal { virtual void Roar() { std::cout << "Roar!\n"; } };
class Rabbit : public class Animal { virtual void Roar() {
    std::cout << "Rabbits don't roar, silly!\n"; } };

typedef void (*NonVirtualCallbackType)(Animal *);

void Callback(Animal *foo)
{
    //Virtual call happens inside the callback
    foo->Roar();
}

void FunctionUsingCallback(NonVirtualCallbackType callback, Animal *instance)
{
    callback(instance);
}

int main()
{
    std::unique_ptr<Animal> generals(new Animal());
    std::unique_ptr<Animal> wabbits(new Rabbit());
    FunctionUsingCallback(Callback, generals);
    FunctionUsingCallback(Callback, wabbits);
}

请注意,这种转换正是 std::mem_fun 在 STL 函子的幕后所做的事情,尽管它依赖于编译时而不是运行时多态性。

Define a non-virtual function that calls the virtual function for you, and attach the non-virtual function to the callback.

#include <memory>
#include <iostream>

class Animal { virtual void Roar() { std::cout << "Roar!\n"; } };
class Rabbit : public class Animal { virtual void Roar() {
    std::cout << "Rabbits don't roar, silly!\n"; } };

typedef void (*NonVirtualCallbackType)(Animal *);

void Callback(Animal *foo)
{
    //Virtual call happens inside the callback
    foo->Roar();
}

void FunctionUsingCallback(NonVirtualCallbackType callback, Animal *instance)
{
    callback(instance);
}

int main()
{
    std::unique_ptr<Animal> generals(new Animal());
    std::unique_ptr<Animal> wabbits(new Rabbit());
    FunctionUsingCallback(Callback, generals);
    FunctionUsingCallback(Callback, wabbits);
}

Note that this kind of conversion is exactly what std::mem_fun does under the covers for STL functors, though it relies on compile time rather than runtime polymorphism.

美男兮 2025-01-15 01:32:35

鉴于您评论中的解释,似乎您需要:

  • 使 MyGUI.h 中的代码了解 Animal

  • 为指向唯一 Animal 实例的指针定义

也许类似this:

// MyGUI.h 
#include "Animal.h"

Class MyGUI : public wxFrame {

  ...
  protected:
     virtual void onFeedButton_cb( wxCommandEvent& event ) {
        Animal::getTheAnimal()->Feed();
        event.Skip(); }
  ...
}

// Animal.h 
Class Animal {
  private:
       static Animal* theAnimal;

  public:
       static Animal& getTheAnimal() { return *theAnimal; }

  public:
       Animal() { theAnimal = this; }

  public: 
       void Feed(); 
}

另请参阅 Singleton 模式。

Given the explanations in your comments, it seems you need to:

  • make the code in MyGUI.h aware of Animal

  • define a global storage for a pointer to the only Animal instance

Perhaps something like this:

// MyGUI.h 
#include "Animal.h"

Class MyGUI : public wxFrame {

  ...
  protected:
     virtual void onFeedButton_cb( wxCommandEvent& event ) {
        Animal::getTheAnimal()->Feed();
        event.Skip(); }
  ...
}

// Animal.h 
Class Animal {
  private:
       static Animal* theAnimal;

  public:
       static Animal& getTheAnimal() { return *theAnimal; }

  public:
       Animal() { theAnimal = this; }

  public: 
       void Feed(); 
}

See also the Singleton pattern.

拔了角的鹿 2025-01-15 01:32:35

对我有用的是:

class MyGUIChild : public MyGUI {
    Animal* animal_ptr; 

    void onFeedButton_cb( wxCommandEvent& event ) { 
        animal_ptr->feed(); 
    }
 }

What worked for me was this:

class MyGUIChild : public MyGUI {
    Animal* animal_ptr; 

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