C++ - 你能用不同的参数重载一个函数但只定义一次吗?

C++ - Can you overload a function with different parameters but define it only once?

我是 c++ 的初学者,我正在尝试制作一个简单的命令行游戏。我有三个 classes:

class DynamicEntity : public Entity { // Entity class has only int x, y variables and getters/setters
    protected:
        enum direction {RIGHT = 77, LEFT = 75, UP = 72, DOWN = 80};
    public:
        posWrap getNextPos(); // Returns the xy coordinates of the entity's next position in a struct called posWrap
};

class Player : public DynamicEntity {
    private:
        int wishdir;
    public:
        int ammoCount = 0;
        posWrap getNextPos(); // Same concept as above, but takes input
};

class CollisionHandler {
    public:
        static char checkCollisions(DynamicEntity& dEntity); // Checks the next position of the entity for collisions and returns what it would collide with
        static char checkCollisions(Player& player); 

};

你看,我重载了 checkCollisions 方法。并定义了 DynamicEntity 版本:

char CollisionHandler::checkCollisions(DynamicEntity& dEntity) {
    int x = dEntity.getNextPos().x;
    int y = dEntity.getNextPos().y;

    return readChar(x, y);
}

getNextPos 函数的实现对于 PlayerDynamicEntity 是不同的,因为第一个函数从玩家那里获取输入,而后者从其他地方获取命令该程序。 我想知道是否可以将 Player class 传递给 checkCollisions 并在方法内部使用 getNextPosPlayer 版本,而无需明确编写 checkCollisions 的另一个定义。我认为这是可能的,因为 PlayerDynamicEntity 的 child。还是我对编译器的要求太多了?

如果您有任何其他建议、批评或更好的方法来完成这些工作,请告诉我。我正在尝试了解更多关于这些主题的信息 in-depth。提前致谢!

答案是使DynamicEntiry::getNextPos成为虚函数并在Player

中覆盖它
class DynamicEntity : public Entity { // Entity class has only int x, y variables and getters/setters
    protected:
        enum direction {RIGHT = 77, LEFT = 75, UP = 72, DOWN = 80};
    public:
        virtual posWrap getNextPos(); // virtual keyword is mandotary here. Allow sub-class to override it.
};

class Player : public DynamicEntity {
    private:
        int wishdir;
    public:
        int ammoCount = 0;
        virtual posWrap getNextPos() override; // the virtual keyword here is optional. The override keyword makes sure you are overriding.
};

class CollisionHandler {
    public:
        static char checkCollisions(DynamicEntity& dEntity);

};

您当然可以将 Player 对象传递给 checkCollisions

Player player;
CollisionHandler::checkCollisions(player);

如果您是虚函数的新手,您可能想阅读一些书籍或文章:https://www.geeksforgeeks.org/virtual-function-cpp/

你可能也对双调度技术感兴趣,这是一种更复杂但也更强大的设计:https://en.wikipedia.org/wiki/Double_dispatch#Double_dispatch_in_C++

I want to know if it is possible to pass in a Player class to checkCollisions and inside the method, use the Player version of getNextPos, without explicitly writing another definition of checkCollisions.

您似乎误解了重载和虚拟分派的工作原理。这个函数

static char checkCollisions(DynamicEntity& dEntity);

可以用Player调用。您不需要其他重载。尽管要使其按预期工作,您应该将 getNextPos() 声明为虚拟的,这样当使用 Player& 调用 checkCollisions(DynamicEntity&) 时,它将调用 Player::getNextPos():

class DynamicEntity {
    public:
        virtual posWrap getNextPos();
      //^^
        virtual ~DynamicEntity(){} // polymorphic types need a virtual destructor
};

class Player : public DynamicEntity {
        posWrap getNextPos() override; // <- add override to help with typos               
};

class CollisionHandler {
    public:
        static char checkCollisions(DynamicEntity& dEntity);    
};

PS:

Can you overload a function with different parameters but define it only once?

没有。您不能调用没有定义的函数。如果您真的尝试它,您会收到链接器错误。