我试图使一个类从其他继承,并重写一些方法。类“标题”是:
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
,还是只是定义一个基本类型?如果只是定义基本类型(我建议),则可以将interseca
,breakNormal
和normal
设为纯虚拟。然后,编译器将遇到您在此处遇到的问题。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";