3

これが私の質問のクラスです

class Graph {}
class SceneGraph : public Graph {}

class Node {
public:
    virtual Node* getNode(int index) { return mNodeList[index]; }

protected:
    vector<Node*> mNodeList;
    Graph* mGraph;
}

class TransformationNode : public Node {
public:
    TransformationNode* getNode(int index) { return static_cast<TransformationNode*> (mNodelist[index]); }

    void _update() {
        auto beg = mNodeList.begin();
        auto end = mNodeList.end();
        while (begin != end) {
            TransformationNode* node = static_cast<TransformationNode*> (*beg);
            node->_update();
        }
    }

private:
    bool mUpdated;
    SceneGraph* mGraph;    
}

まず、私が解決した問題についてお話したいと思います。彼らは他の人を助けるかもしれません。そして、私が正しいかどうかを確認できます^^

  1. 戻り値の型が異なる関数をオーバーライドできますか?
    Node* getNode(int index) は TransformationNode* getNode(int index) になりました

    はい、戻り値の型が共変である限り: http://www.tolchz.net/?p=33

  2. メンバーをオーバーライドできますか?

    オーバーライドについてはわかりませんが、派生クラスの同じ名前の変数は、基本クラスの変数を非表示にします

そして、私が本当にどうにかして回避したい問題があります

TransformationNode クラスでは、基本クラスから派生クラスへの多くの (IMHO) 回避可能な型キャストを行いました。mNodeList ベクトルのすべての要素が TransformationNodes であることは確かにわかっていますが、mNodeList を処理するには、それらを型キャストする必要があります。

継承は正しいです。つまり、TransformationNode は

ノードであり、mNodeList はノードの子ノードを保持し、型キャストされたバージョンのノードを保持する派生クラスにコピーを持つことはできません

。最後に、static_cast の方がコストがかかる場合は reinterpered_cast を使用することもできます。これらの操作の費用について教えていただけますか? それらは本当に大きなパフォーマンスの問題ですか?
assert (dynamic_cast)... ある種の予防策はすでに講じられています。



簡単に言うと、mGraph が実際には SceneGraph* であり、mNodeList が TransformationNode* を保持していることをコンパイラーに認識させたいと考えています。これにより、型キャストが失われるのを防ぐことができます。


お時間をいただきありがとうございます

4

1 に答える 1

1

1)正しいです。戻り値の型がより派生している場合、実際に(仮想!)基本関数をオーバーライドできます。

広告 2): 実際、メンバーを「オーバーライド」することはできません。より柔軟なオーバーライド可能な動作が必要な場合は、基本クラスを再設計してください。

static_castコンパイル時に解決される静的操作reinterpret_castであり、「コスト」がないのと同じです。


@Seth がコメントで示唆しているように、コンテナーを移動するオプションになる可能性があります。自問してみてください、abstract が存在することはあり得るのNodeでしょうか、それともすべてのノードが実際に派生した具象型であるでしょうか? おそらくあなたはNode抽象化することができます:

struct Node { Node * getNode(size_t index) const = 0; };

struct TransformNode : Node
{
    TransformNode * getNode(size_t index) const { return m_nodes[index]; }
private:
    std::vector<TransformNode *> m_nodes;
};

インターフェイス全体を基本クラスに入れますが、各具象クラスにのみ実装します。

于 2012-01-14T23:53:03.263 に答える