在C++中使用Overriding感到困惑

est*_*arb 2 c++ overriding

我正在尝试使一个类继承自其他类并重写一些方法.类'标题'是:

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
};
Run Code Online (Sandbox Code Playgroud)

接下来在程序的其他地方(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);
Run Code Online (Sandbox Code Playgroud)

我想要的interseca是在Esfera中调用它的新版本.通过这种方式,我可以添加更多对象(立方体,三角形等)并将它们视为通用的"Objetos".

而不是Esfera实现interseca的程序调用Objeto::interseca.

使用C++进行覆盖的正确方法是什么?这是覆盖的方式,我错过了什么,或者我是完全错的?任何提示或替代方法吗?

Mer*_*ham 7

如果通过指针或引用访问类,则只能获得多态行为.除此之外,在将派生类型复制到非指针/非引用基类型时,您正在切片对象.

切片:

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;
    }
};
Run Code Online (Sandbox Code Playgroud)

这不会做你想要的:

Esfera e;
Objeto o = e;
std::cout << o.interseca() << "\n";
Run Code Online (Sandbox Code Playgroud)

但这会:

Esfera e;
Objeto& o = e;
std::cout << o.interseca() << "\n";
Run Code Online (Sandbox Code Playgroud)

真正

程序设计

您可以用来避免将来使用的技术是使您的基类(纯)抽象.

你会Objeto在你的场景中实例化一个真实的,还是只是定义一个基类型?如果你只是一个确定的基类(我推荐),那么你可以做interseca,breakNormalnormal 纯虚.然后,编译器将捕获像您在这里的问题.

class Objeto {  
public:  
    virtual bool interseca() = 0;
};

class Esfera: public Objeto {
public:
    int idMaterial;

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

// ...
Run Code Online (Sandbox Code Playgroud)

那么,这没关系:

Esfera e;
Objeto& o = e;
std::cout << o.interseca() << "\n";
Run Code Online (Sandbox Code Playgroud)

汇编成功了

但这会导致编译器出错 - 这是一件好事,因为它会捕获一个bug:

Esfera e;
Objeto o = e;
std::cout << o.interseca() << "\n";
Run Code Online (Sandbox Code Playgroud)

错误:无法分配抽象类型'Objeto'的对象