【问题标题】:Call method of derived class派生类的调用方法
【发布时间】:2012-05-31 14:51:12
【问题描述】:

我正在做一个管理项目集合的程序。这可以是一本书、一本杂志、一张 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();

如何调用这些方法?

【问题讨论】:

    标签: c++ list class


    【解决方案1】:

    这里至少有两个问题。首先,如果你这样做:

    list<Item> items;
    

    那么这个列表真的只会包含Item 对象;如果您尝试放入派生对象,则派生部分将只是sliced off

    一种解决方案是改用指针列表(尽管您可能应该使用智能指针来避免内存管理问题)。

    但即便如此,第二个问题是您不应该(通常)尝试通过指向基类的指针来调用特定于派生类的方法。多态性的全部意义在于,如果您乐于使用整个层次结构共有的功能,则应该只处理基类指针(请参阅Liskov substitution principle)。

    【讨论】:

    • 好的,我怎样才能创建一个能够存储任何派生类对象的列表?
    • 您需要使用 list 而不是 list。引用是多态的。
    • 以及如何访问这些项目?并将项目添加到列表中?
    • @carleeto:引用是多态的,但不是对象。由于list 只能包含对象,因此您无法创建list&lt;T&amp;&gt;。这就是 Oli 提出指针列表的原因:指针既是多态的又是对象。
    【解决方案2】:

    您可能应该在class Item 中定义virtual void show() = 0;。这将使show 调用合法,但同时会导致list&lt;Item&gt; 出现错误。

    根本的错误是你不能拥有“只是”Item 的东西,但list&lt;Item&gt; 会尝试列出准确的列表。通过在Item 中将show 声明为纯虚函数,编译器明确知道这一点。

    【讨论】:

      猜你喜欢
      • 2016-01-01
      • 2012-09-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-17
      • 2014-09-05
      • 2015-04-08
      相关资源
      最近更新 更多