强制调用 "highest" 重载函数而不是基函数

Force call to "highest" overloaded function instead of base function

我有一个基础 class 和许多其他 classes(全部派生自基础 class),它们都使用相同的参数实现相同的功能。我的问题如下:

class Entity
{
public:
    int getx();
    int gety();
};

class Enemy : public Entity
{
public:
    int getx();
    int gety();
};

class Player : public Entity
{
public:
    int getx();
    int gety();
};

// all of the implementations actually differ

int distance(Entity *e1, Entity *e2)
{
    return e2->getx() + e2->gety() - e1->getx() - e2->gety();
    // here, it is always Entity::getx and Entity::gety that are called
}

我想要的是,如果我用 eEnemypPlayer 调用 distance(e, p),相应的函数重载被调用,而不是实体的实现。

如果真的可行,我将如何实现?我在这里搜索了很多,我发现最接近的问题是在完全不同的上下文中使用模板,所以它并没有真正帮助我:Template function overload for base class

提前致谢。

正如@Amit 在评论中所述,您正在寻找虚函数。您可以按如下方式更新 Entity class:

class Entity
{
public:
    // Add a virtual destructor to allow deletion through base pointer to work correctly
    // (e.g., E* e = new Player(); delete e;)
    virtual ~Entity();

    virtual int getx() const = 0; // 'const' isn't related to your question but
    virtual int gety() const = 0; // good to have, '= 0' is optional but helpful if
                                  // the base class isn't providing an implementation
};

假设是 C++11,在派生的 classes 中使用 override 也很好。

class Enemy : public Entity
{
public:
    // 'const' only necessary if specified in the base class
    // 'virtual' is more documentation it would still be virtual if omitted
    // 'override' enforces that the signature matches a virtual function
    virtual int getx() const override;
    virtual int gety() const override;
};

你要做的实际上是OOP中的基本概念之一:虚函数.

这个想法和你描述的完全一样:

A virtual function is a function that's being replaced by subclasses implementation when accessed via a base class pointer.

语法非常简单,只需将关键字 virtual 添加到基础 class 函数声明即可。使用 override 关键字标记重写函数(子 classes 的函数)是一种很好的做法(尽管不是必需的)。

这是 reference of virtual functions.

您可以将代码更改为:

class Entity
{
public:
    virtual int getx();
    virtual int gety();
};

class Enemy : public Entity
{
public:
    int getx() override;
    int gety() override;
};

class Player : public Entity
{
public:
    int getx() override;
    int gety() override;
};

// all of the implementations actually differ

int distance(Entity *e1, Entity *e2)
{
    return e2->getx() + e2->gety() - e1->getx() - e2->gety();
    // Now, the proper getx & gety are being called
}