我正在做一个管理项目集合的程序。这可以是书,杂志,CD或DVD。每个都是一个继承类Item的类。要存储我正在使用列表模板的项目,如下所示:
list<Item> items;
,此列表位于类库的对象库中。
要浏览此列表,我正在执行此操作:
for(list<Item>::iterator i = lib.itens.begin(); i != lib.itens.end(); ++i)
在此之前一切都很好。当我尝试在此循环中调用派生类的方法时,问题就开始了。例如:
for(list<Item>::iterator i = lib.itens.begin(); i != lib.itens.end(); ++i)
(*i).lib.itens.show();
如何调用这些方法?
答案 0 :(得分:2)
这里至少有两个问题。首先,如果你这样做:
list<Item> items;
那么这个列表实际上只包含Item
个对象;如果您尝试放入派生对象,派生部分将只是sliced off。
一种解决方案是使用指针列表(尽管您应该使用智能指针来避免内存管理问题)。
但即便如此,第二个问题是你不应该(通常)试图通过指向基类的指针调用派生类特定的方法。多态性的全部意义在于,如果您乐于使用整个层次结构中常见的功能,那么您应该只处理基类指针(参见Liskov substitution principle)。
答案 1 :(得分:0)
您可能应该在virtual void show() = 0;
中定义class Item
。这会使show
调用合法,但同时会导致list<Item>
出错。
根本的错误是你不能拥有“只是”Item
的东西,但list<Item>
会尝试制作一个恰好相同的列表。通过在show
中将Item
声明为纯虚函数,编译器明确地知道这一点。