c++多态性和列表

c++ polymorphism and list

本文关键字:列表 多态性 c++      更新时间:2023-10-16
struct struct_unit{};
struct struct_unit_rotable : struct_unit {};
std::list <struct_unit> unitsList;

struct_unit *su=new struct_unit_rotable;
unitsList.push_front(*su);

然后我有两种绘制方法:

void drawUnit(struct_unit &su);
void drawUnit(struct_unit_rotable &su);

当我调用drawUnit(unitsList.front());-错误的不可旋转绘制方法被称为

如何正确插入struct_unit_rotable类型转换为list,那么unitsList.front()将返回类型struct_unit_rotable

您误解了多态性。多态性的思想是允许派生类为基类中声明的virtual方法提供实现,但使用基类的指针或引用来访问该实现(如果直接使用对象,它们将被切片,请参阅David的回答(。在您的案例中,没有这样的声明,因此也没有多态性。

要调用多态性,您需要

struct unit
{
  virtual void draw();
  virtual ~unit();      // important
};
struct unit_rotatable   // did you really mean 'rotable'?
 : unit
{
  virtual void draw();         // 'virtual' needed only for another level of polymorphism
  virtual ~unit_rotatable();
}

并通过调用它们

std::list <std::unique_ptr<unit>> unitsList;      // we need pointer (or reference) to base
unitList.emplace_front(new unit_rotatable);
unitList.front()->draw();                         // calls unit_rotatable::draw()

我使用unique_ptr来确保在销毁unitsList时自动取消分配对象。

您的列表将包含struct_unit类型的对象。如果你将struct_unit_rotable类型的对象传递给它,它们将得到切片

即使您使用指针,也只会调用void drawUnit(struct_unit*su(,您也需要将多态性放入结构中,正如Walter所展示的

只要您将对象插入为struct_unit,您总是会得到这种对象,并且您调用的drawUnit函数将始终是struct_unit。难道你不能在对象内部移动drawUnit((函数并创建一个类吗?如果将函数设为虚拟函数,则可以调用正确的函数。

这是多态性的一个很奇怪的用法。更好的方法是struct_unit中的virtual drawUnit()将在struct_unit_rotable中被覆盖。

我手头没有标准,但我确信,对于struct_unit类型的矢量内容,如果不进行强制转换,就没有合适的方法来检测最合适的方法。

请参阅此处了解相关问题:将重载函数与其多态参数匹配据称,重载解析是在编译时完成的。您的代码在执行期间需要重载解析,因为不清楚在编译期间将在向量中放置什么类型。

我明白你想做什么了。有一种非常巧妙的方法可以做到这一点,在本视频中介绍,我建议任何人学习。

http://channel9.msdn.com/Events/GoingNative/2013/Inheritance-Is-The-Base-Class-of-Evil【继承是邪恶的基类】[1]

这里的基本前提是"继承应该是一个实现细节,而不是一个接口"。

我以这种方式工作得越多,我就越高兴。