【问题标题】:C++ - Can you overload a function with different parameters but define it only once?C++ - 你可以用不同的参数重载一个函数但只定义一次吗?
【发布时间】:2021-05-14 11:30:57
【问题描述】:

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

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 类传递给checkCollisions 并在方法内部使用getNextPosPlayer 版本,而无需明确编写checkCollisions 的另一个定义。我认为这是可能的,因为PlayerDynamicEntity 的孩子。还是我对编译器的要求太高了?

如果您有任何其他建议、批评或更好的方法来做这件事,请告诉我。我正在尝试更深入地了解这些主题。提前致谢!

【问题讨论】:

  • "我想知道是否可以将Player 类传递给checkCollisions" - 你有没有尝试过这样做?
  • 一种显而易见的答案是使用虚函数,所以我对你的问题感到困惑。无论如何,作为这里的新用户,请使用tour 并阅读How to Ask

标签: c++ overloading


【解决方案1】:

我想知道是否可以传入一个 Player 类来 checkCollisions 并在方法内部使用 getNextPos 的 Player 版本,而无需显式编写另一个 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:

你能重载一个带有不同参数但只定义一次的函数吗?

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

【讨论】:

    【解决方案2】:

    答案是将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++

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-21
      • 2023-03-15
      • 1970-01-01
      • 1970-01-01
      • 2020-12-23
      • 1970-01-01
      • 2018-01-20
      • 2015-01-30
      相关资源
      最近更新 更多