指向类成员函数的指针

时间:2017-03-07 12:37:40

标签: c++ class pointers

我有两个类,Messaging和GameObject。每个GameObject对象都有一个Messaging实例,我需要在Messaging中有一个指向GameObject中函数的函数指针。

此外,还会有来自GameObject的类中的对象应该具有相同的对象(在Messaging实例中指向其中的函数的函数指针)。

下面是GameCharacter对象(派生自GameObject)提供要调用其Messaging实例的函数的代码:

messaging->Register(GameCharacter::DoMessage);

这是我的Messaging类代码:

/// Allows an object to send and receive messages.
class Messaging : public Component, public ::Messaging
{
private:

    // Forward declaration of GameObject
    class GameObject {};

    // Define the OnMessageType as a function pointer to a function
    // taking Message as parameter and returning void.
    typedef void (GameObject:: *OnMessageType)(Message);

    // OnMessage function pointer;
    OnMessageType OnMessage;

public:

    // Assign a function to the function pointer
    void Register(OnMessageType func) { OnMessage = func; }

    // Forward the Message to the function pointed to by the function pointer
    void DoMessage(Message msg) { (this->*OnMessage)(msg); };

};

GameObject类:

class GameObject
{
    public:

        /// Unique number used for identification
        int id;

        /// Reference to the graphical model displayed by this object
        int modelReference;

        /// GameObject children
        std::vector<GameObject> children;

        /// Constructor
        GameObject();

        /// Destructor
        ~GameObject();

        /// Add a child GameObject node
        void AddChild(GameObject child);

        /// Update Object
        virtual void Update();

        /// Handles received messages
        //virtual void DoMessage(Message msg);

        // Provide pointers to all possible components
        Components::Transform* transform;
        Components::RigidBody* rigidBody;
        Components::Messaging* messaging;

        // Pointer to message queue
        //std::vector<Message> *msgQueue;

    private:
        /// Send message
        void SendMessage(Message msg);
};

GameObject对象将使用OnMessage应指向的函数调用Register。然后,当调用DoMessage时,应该调用GameObject中指向的函数。因此,在这种情况下,调用DoMessage(在GameCharacter的Messaging实例中)应该依次调用GameCharacter对象中的DoMessage。

问题是我在DoMessage(Message msg)函数上遇到了这个错误:

  

成员类型指针'void   (Components :: Messaging :: GameObject ::)(Message)'与之不兼容   对象类型'Components :: Messaging'

从我可以收集它对指针函数类型的不满。我已经读过(在堆栈溢出帖子上),当调用指针函数时,应该指定成员函数所属的类型但我找不到如何做...

有没有人可以解释一下这个问题并解释我如何修复我的代码?

2 个答案:

答案 0 :(得分:2)

std::functionstd::bind一起使用,而不是使用函数指针。您收到此类错误的原因是您没有接收函数调用的对象,但您只有一个函数。如果需要通过指针调用成员函数,则必须保留两件事:

  1. 一个函数指针
  2. 您保留的成员函数指针的类的对象
  3. 实现所需内容的最佳方式是将std::functionstd::bind一起使用。例如:

    using namespace std::placeholders;
    GameCharacter gameCharacter;
    messaging->Register(std::bind(GameCharacter::DoMessage, gameCharacter, _1));
    

    Messaging类必须接受std::function<void(Message)>对象类型。

    class Messaging : public Component, public ::Messaging
    {
    private:
    
        // Forward declaration of GameObject
        class GameObject {};
    
        // Define the OnMessageType as a function pointer to a function
        // taking Message as parameter and returning void.
        //typedef void (GameObject:: *OnMessageType)(Message);
        typedef std::function<void(Message)> OnMessageType;
    
        // OnMessage function pointer;
        OnMessageType OnMessage;
    
    public:
    
        // Assign a function to the function pointer
        void Register(OnMessageType func) { OnMessage = func; }
    
        // Forward the Message to the function pointed to by the function pointer
        void DoMessage(Message msg) { this->OnMessage(msg); };
    
    };
    

答案 1 :(得分:1)

Messaging不会从GameObject继承,因此您无法使用this个实例来调用OnMessage

您需要GameObject的实例来调用成员方法。

 GameObject gameObject;

 (gameObject.*OnMessage)(msg);
 // or (gameObject.*this->OnMessage)(msg);

但不确定这是你想做的事。

也许你真的想要std::function<void(Message )> ......