强制调用 "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
}
我想要的是,如果我用 e
和 Enemy
和 p
和 Player
调用 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
}
我有一个基础 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
}
我想要的是,如果我用 e
和 Enemy
和 p
和 Player
调用 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
}