我有一个我希望流出的SceneElements集合。这是聚合类:
class scene{
public:
vector<sceneElement> elements;
void addElement(sceneElement);
void toStream(std::ostream &);
void fromStream(std::istream &);
};
void scene::addElement(sceneElement e){
elements.insert(elements.end(), e);
}
void scene::toStream(std::ostream &strm){
strm << SCENE_PRE;
int i;
for(i=0; i<elements.size(); i++){
elements[i].toStream(strm);
}
strm << SCENE_POST;
}
这是基类:
class sceneElement{
public:
virtual void toStream(std::ostream &);
virtual void fromStream(std::istream &);
};
void sceneElement::toStream(std::ostream &str){
str << "SCENE ELEMENT";
}
void sceneElement::fromStream(std::istream &){
std::cerr << "this is not supposed to be called";
}
,这是派生类之一:
class camera : public sceneElement{
public:
P3d location;
P3d direction;
double fov;
int toString(char**);
virtual void toStream(std::ostream &);
virtual void fromStream(std::istream &);
};
void camera::toStream(std::ostream &strm){
strm << CAMERA_PRE << TAG_LOCATION;
location.toStream(strm);
strm << TAG_DIRECTION;
direction.toStream(strm);
strm << TAG_FOV << fov << CAMERA_POST;
}
但是当我运行此代码时:
scene sc;
sc.addElement(s);
sc.toStream(cout);
显示
<_SCN>SCENE ELEMENT<SCN_>
而不是它应该的实际元素。
答案 0 :(得分:2)
您需要将指针存储到向量中的基类 虽然您认为向向量添加了类对象,但向量中的每个元素只有足够的空间用于Base类对象。因此,实际存储在向量中的只是Base对象部分。派生类内容仅仅 切掉 这种现象在C ++中通常被称为 Object slicing 。
此外,不应将原始指针存储在向量中,而应考虑使用智能指针。
答案 1 :(得分:1)
STL容器不能以多态方式使用,因为它的值语义并且需要同类存储大小。
每个派生对象的大小可以与基础对象的大小不同。
在容器中,很难实现简单的功能,如:
vector<Element> v;
..
int i;
Element e = v [i+5];
如果i和i + 5之间的每个“元素”可以具有不同的大小。
因此,它只使用每个项目的静态类型的大小,即基数。
解决此限制的方法是使用指针容器。因为所有指针都具有相同的大小,无论其类型如何。我们可以多态地使用指针。