【问题标题】:c++ polymorphism and listc++ 多态和列表
【发布时间】:2014-04-23 10:11:43
【问题描述】:
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);

那么我有 2 种绘制方法:

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

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

如何正确插入 struct_unit_rotable 输入list 所以unitsList.front() 将返回类型struct_unit_rotable

【问题讨论】:

    标签: c++ list polymorphism


    【解决方案1】:

    你误解了多态性。多态性的想法是允许派生类为基类中声明为virtual 的方法提供实现,但使用基类的指针或引用来访问该实现(如果您直接使用对象,他们会被切片,见大卫的回答)。在您的情况下,没有这样的声明,因此没有多态性。

    要调用多态性,您需要

    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 销毁时对象的自动解除分配。

    【讨论】:

    • 它看起来很正确,但你正在泄漏内存。此外,任何虚拟类都应该有一个虚拟析构函数(以便delete base_ptr; 正确地析构任何多态对象)。
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 嗯,这是我的备用计划...因为这只是这里显示的部分代码,修改会更复杂
      【解决方案4】:

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

      我手头没有标准,但我确信没有正确的方法没有强制转换来检测最合适的方法,因为它是struct_unit 类型的矢量内容。

      相关问题请参见此处:Matching an overloaded function to its polymorphic argument 据说重载决议是在编译时完成的。您的代码在执行期间需要重载解决方案,因为不清楚在编译期间将在向量中放置什么类型。

      【讨论】:

      • 多态性的用法很奇怪——根本没有多态性。
      • @Walter 我的意思是对多态性的理解很奇怪。对此感到抱歉。不过,我确实理解“多态”对象转换的愿望。
      【解决方案5】:

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

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

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

      我越是这样工作,我就越高兴自己这样做了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-19
        • 1970-01-01
        相关资源
        最近更新 更多