我正在尝试使一个类继承自其他类并重写一些方法.类'标题'是:
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++进行覆盖的正确方法是什么?这是覆盖的方式,我错过了什么,或者我是完全错的?任何提示或替代方法吗?
如果通过指针或引用访问类,则只能获得多态行为.除此之外,在将派生类型复制到非指针/非引用基类型时,您正在切片对象.
切片:
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,breakNormal和normal 纯虚.然后,编译器将捕获像您在这里的问题.
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'的对象
| 归档时间: |
|
| 查看次数: |
229 次 |
| 最近记录: |