我试图使一个类从其他继承,并重写一些方法。类“标题”是:

class Objeto {
public:
    virtual bool interseca(const Rayo &rayo, float magnitud);
    virtual bool breakNormal(const Punto &punto);
    virtual Vector normal(const Punto &punto);

    int idMaterial;
};

class Esfera: public Objeto {
public:
    int idMaterial;

    virtual bool interseca(const Rayo &rayo, float magnitud);
    // etc
};

接下来,在程序的其他地方(Objeto和Esfera之外),我执行以下操作:
// ObjectList is a Vector<Objeto>
Objeto o = esfera; /* Where esfera is a valid Esfera object */
ObjectList[0] = o;
ObjectList[0].interseca(rayo, magnitud);

我想要的是调用Esfera中的interseca的新版本。这样,我可以添加更多对象(多维数据集,三角形等),并将它们视为通用的“Objetos”。

但是,该程序不是interseca的Esfera实现,而是调用Objeto::interseca

用C++进行此覆盖的正确方法是什么?那是重写的方法,我错过了什么还是我完全错了?有什么技巧或替代方法吗?

最佳答案

如果您通过指针或引用访问该类,则只能获得多态行为。除此之外,在将派生类型复制到非指针/非引用基本类型时,还要对对象进行 slice 。

slice :

http://en.wikipedia.org/wiki/Object_slicing

给定这些定义:

#include<iostream>

class Objeto {
public:
    virtual bool interseca() {
        return false;
    }
};

class Esfera: public Objeto {
public:
    int idMaterial;

    virtual bool interseca() {
        return true;
    }
};

这不会做你想要的:
Esfera e;
Objeto o = e;
std::cout << o.interseca() << "\n";



但这将:
Esfera e;
Objeto& o = e;
std::cout << o.interseca() << "\n";



程序设计

将来可以避免使用的一种技术是使基类(纯)抽象。

您是否会在场景中实例化一个真正的Objeto,还是只是定义一个基本类型?如果只是定义基本类型(我建议),则可以将intersecabreakNormalnormal设为纯虚拟。然后,编译器将遇到您在此处遇到的问题。
class Objeto {
public:
    virtual bool interseca() = 0;
};

class Esfera: public Objeto {
public:
    int idMaterial;

    virtual bool interseca()
    {
        return true;
    }
};

// ...

然后,就可以了:
Esfera e;
Objeto& o = e;
std::cout << o.interseca() << "\n";



但这会导致编译器出错-一件好事,因为它捕获了一个错误:
Esfera e;
Objeto o = e;
std::cout << o.interseca() << "\n";

10-01 01:57