1

ストリーミングしたい 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";
}

これは派生クラスの 1 つです。

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_> 

実際の要素ではなく、それが想定されていました。

4

2 に答える 2

2

基本クラスへのポインターをベクターに格納する必要があります。
派生クラス オブジェクトをベクターに追加したと思われますが、ベクター内の各要素には Base クラス オブジェクト用の十分なスペースしかありません。したがって、実際にベクターに格納されるのは Base オブジェクトの部分だけです。派生クラスの内容は、切り捨てられるだけです。この現象は、C++のオブジェクト スライシング
として広く知られています。

また、生のポインターをベクターに格納する代わりに、スマート ポインターの使用を検討する必要があります。

于 2013-01-21T03:45:08.270 に答える
1

STL コンテナーは、その値のセマンティクスと同種のストレージ サイズを必要とするため、ポリモーフィックに使用できません。

各派生オブジェクトは、ベース オブジェクトとは異なるサイズを持つことができます。

コンテナーでは、次のような単純な関数を実装するのは困難です。

vector<Element> v;
..
int i;
Element e = v [i+5]; 

i と i+5 の間の各「要素」が異なるサイズを持つことができる場合。

したがって、すべてのアイテムに対して、静的タイプ、つまりベースのサイズを使用するだけです。

この制限を回避する方法は、ポインターのコンテナーを使用することです。型に関係なく、すべてのポインタは同じサイズです。ポインタをポリモーフィックに使用できます。

于 2013-01-21T04:43:55.397 に答える