代码之家  ›  专栏  ›  技术社区  ›  user2970381

C++将一个成员函数作为参数传递给另一个成员函数

  •  0
  • user2970381  · 技术社区  · 8 年前

    我想将一个成员方法作为参数传递给另一个成员方法。我对此进行了广泛的研究,但仍然无法确定是否正确。我的头文件如下

    #include <string>
    #include <map>
    #include <functional>
    
    #include "Entity.h"
    #include "World.h"
    #include "Item.h"
    
    class Tile;
    
    class Player : public Entity
    {
    private:
        using FunctionPointer = void (Player::*)(Tile*);
        bool victory;
        Point location;
        std::map<char, FunctionPointer> actions;
    
    public:
        Player(std::string name, int gold, int maxHitPoints, int defensePoints, 
               Point startingLocation, int maxDamage = 0, int maxItems = -1,
               std::vector<Item*> inventory = std::vector<Item*>());
    
        std::string getClassName() const override;
    
        void printInventory(Tile*) override; 
        std::string toString() override;
    
        Point getLocation() const;
        Item* findMostPowerfulWeapon();
        void heal(Tile*);
        void moveNorth(Tile*);
        void moveSouth(Tile*);
        void moveEast(Tile*);
        void moveWest(Tile*);
        void attack(Tile* tile);
        void pickup(Tile* tile);
        void trade(Tile* tile);
    
        void getAvailableActions(Tile* tile);
        void chooseAction();
    
    private:
        void move(int dx, int dy);
        void actionAdder(char hotkey, FunctionPointer, std::string name);
    }; 
    

    cpp文件中给我带来问题的部分如下:

    void Player::getAvailableActions(Tile * tile)
    {
        actions.clear();
        std::cout << "Choose an action:" << std::endl;
        if (getInventory().size() > 0)
            actionAdder('i', (this->*(&Player::printInventory))(tile), "Print inventory");
        if (tile->getClassName() == "Trader")
            actionAdder('t', (this->*(&Player::trade))(tile) , "Trade");
        if (tile->getClassName() == "Monster")
            actionAdder('a', (this->*(&Player::attack))(tile), "Attack");
    }
    
    void Player::actionAdder(char hotkey, FunctionPointer action, std::string name)
    {}
    

    Visual studio在所有三个this(this->*(&Player::attack))(tile)前面标记括号,并给出工具提示“void”类型的参数与“Player::FunctionPointer”类型的参数不兼容。如果我尝试编译,我得到的编译器错误是“void Player::actionAdder(char,Player::FunctionPointer,std::string)”:无法将参数2从“void”转换为“Player::FunctionPointer”。

    如果有人知道我做错了什么,我将不胜感激。如果您需要查看更多代码或更多详细信息,请告诉我。代码不是超级机密。

    谢谢

    1 回复  |  直到 8 年前
        1
  •  2
  •   Barry    8 年前

    仔细阅读错误消息:

    类型为“”的参数 void “” 与类型的参数不兼容

    无法转换 参数2来自' 无效的 ' 至' Player::FunctionPointer '。

    这是因为这里的参数2:

    actionAdder('i', (this->*(&Player::printInventory))(tile), "Print inventory");
    

    实际上是 调用 printInventory 并试图将调用结果传递到 actionAdder() 。但那是一个 无效的 函数,并且不能传递类型为 无效的 对于其他的东西-因此错误的抱怨正是这样。

    您不想调用 打印库存 ,您只想传递一个指向它的指针。那只是:

    actionAdder('i', &Player::printInventory, "Print inventory");