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

标签 c++ pointer-to-member

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

#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),并给出工具提示“argument of type “void” is incompatible with parameter of type”播放器::函数指针""。如果我尝试编译,我得到的编译器错误是“void Player::actionAdder(char,Player::FunctionPointer,std::string)”:无法将参数 2 从“void”转换为“Player::FunctionPointer”。

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

谢谢

最佳答案

仔细阅读错误信息:

argument of type "void" is incompatible with parameter of type

cannot convert argument 2 from 'void' to 'Player::FunctionPointer'.

那是因为这里的论点 2:

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

实际上是调用 printInventory 并尝试将该调用的结果传递给actionAdder()。但那是一个 void 函数,您不能将 void 类型的东西传递给其他东西 - 因此错误正是提示这一点。

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

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

关于C++ 将成员函数作为参数传递给另一个成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49604139/

相关文章:

c++ - 为什么 std::sort() 会改变排序后的 vector ?

c++ - 运行 SURF 演示代码时出错

c++ - 带有初始化变量和负数的 memcpy

c++ - 使用对嵌入的双端队列成员的引用初始化的树元素会为此导致 nullptr

c++ - 检查函数指针是否被注册

c++ - 通过资源文件获取opengl的纹理图片(c++/visual studio 2008)

oop - Fortran:指向方法的过程指针

c++ - 不能取消引用类型定义结构指针的成员

c++ - 如何编写一个通用的 "getData"函数?

c++ - 向上转换函数指针安全吗?