2

私はPathextendsstd::vector<Square *>というSquareクラスを持っています。これも私が作成したクラスです。はPath、エンティティが 2D 環境を横断するためのガイドとして機能します。達成可能な最長パスと最短パスを取得する必要があるため、Squaresaで 2 つの間の正方形の数を見つけようとしていPathます。これを行うには、をオーバーロードするのが有益だと思いstd::vector<Square *>::push_back(const value_type &__x)ますが、その構文がどうなるかはわかりません。私は現在これを試しています:

class Path : public std::vector<Square *>
{   //... functional stuff, not relevant. 
    int length;
public:
    push_back(const value_type &__x)
    {   Square *last_square = this->at(this->size() - 1);

        // how do I call super class push_back?
        // however that works, I push back &__x square here.

        Square *most_recent = (Square *)&__x;
        int delta_x = compare_distance(last_square, most_recent);
        length += delta_x;
    };
    int path_length() { return length; };
};

もちろん、スーパークラスの push_back を呼び出すメソッドを書くこともできると思いますが、関数をオーバーライドする方が簡潔であると感じます。また、stl 関数を適切にオーバーライドする方法を学ぶことは良い習慣です。

ありがとう!

4

4 に答える 4

18

さらに、stl 関数を適切にオーバーライドする方法を学ぶことは、私にとって良い習慣です。

実際、そうではありません。

STL コンテナーは継承 (virtualメソッドなし) することを意図していないため、コンポジションを使用し、目的を達成するために STL コンテナー メソッドを使用する意味のあるインターフェイスをクラスに提供することをお勧めします。

于 2012-12-12T09:46:39.107 に答える
3

を使用しているという事実std::vectorは、単なる実装の詳細です。std::list、またはstd::set.

これは、タイプにあまり強くコミットしてはならないという手がかりを与えるはずです。

継承するのではなく集約します。あなたは再利用するために継承しますが、それはあなたが必要としているものではないと思います。

さらに、標準コンテナーを使用する正しい方法は、それらから継承しないことです。仮想デストラクタはなく、オーバーライドする仮想関数もありません。

于 2012-12-12T10:02:04.530 に答える
0

他のものに追加するには、この場合、構成またはプライベート継承 (implemented-in-term-of) を使用します。

経験則として、質問をして、どちらが正しいかに基づいて何を使用するかを決定します。

  • パスは std::vector の観点から実装されています

また

  • パスは std::vector です

「Path is a std::vector」の方が正確な場合 (つまり、Path を std::list、std::deque、または MyFunnyContainer にすることはできません)、std::vector から派生します。「パスはstd::vectorの観点から実装されています」がより正確な場合は、合成またはプライベート継承を使用してください。

于 2012-12-12T12:44:46.097 に答える