6

背景情報: 私と数人の友人は、学校の課題で sfml と box2d の助けを借りて、C++ でこのプラットフォーム ゲームを構築しています。要件の 1 つは、「MVC パターン」に従うことです。

モデル用に Bullet や Character などのクラスを作成しました。ビューには BulletView と CharacterView (どちらも抽象クラスである sf::Drawable を継承しています)。

描画用のコードを複製する代わりに、このように drawBullets と drawCharacter の 2 つのメソッドを用意します。

void WorldView::drawBullets()
{
    std::vector<BulletView*>::iterator it;
    for ( it = bullets.begin() ; it < bullets.end(); it++ )
        window->draw(**it);
}

void WorldView::drawCharacters()
{
    std::vector<CharacterView*>::iterator it;
    for ( it = characters.begin() ; it < characters.end(); it++ )
        window->draw(*it);
}

次のようなポリモヒズムを使用した、より一般的な方法が必要です。

void WorldView::drawVector(const std::vector<sf::Drawable*>& vector)
{
    std::vector<sf::Drawable*>::iterator it;
    for ( it = vector.begin() ; it < vector.end(); it++ )
        window->draw(**it);
}

bulletView ベクトルは次のように宣言されます。

std::vector<BulletView*> bullets;

しかし、これを機能させることはできません。そして、私はC ++を初めて使用するので、ご容赦ください! 検索してみましたが、あまり具体的な答えは見つかりませんでした。

コンパイル中に発生するエラー。

エラー 8 エラー C2679: バイナリ '=' : タイプ 'std::_Vector_const_iterator<_Myvec>' の右側の >オペランドを取る演算子が見つかりません (または、受け入れ可能な >変換がありません) c:\users\niklas\multiplaya\ sfml test\sfml test\view\worldview.cpp 409 >1 SFML_Test

エラー 7 エラー C2664: 'mp::WorldView::drawVector' : パラメーター 1 を >'std::vector<_Ty>' から 'const std::vector<_Ty> &' c:\users\niklas\multiplaya に変換できません\sfml >test\sfml test\view\worldview.cpp 402 1 SFML_Test

4

4 に答える 4

6

問題は、ポリモーフィズムがベクトルのレベルでは機能せず、ベクトルに含まれるポインターのレベルで機能することです。完全に異なる型であるため、として渡すstd::vector<Derived*>ことはできません。ただし、 をへのポインタでstd::vector<Base*>埋めることはできます。std::vector<Base*>Derived*

したがって、弾丸ベクトルを次のように宣言する必要があります。

std::vector<Drawable*> bullets;

BulletView*たとえば、次のように入力します。

bullets.push_back( new BulletView( some args) );

drawVector(bullets);

: 上記のコードでは、動的に割り当てられたオブジェクトの所有権の問題を回避しています。BulletViews明らかに、適切なタイミングでを削除するためのメカニズムが必要です。

于 2012-05-04T09:05:48.317 に答える
3

ポリモーフィック ベクトルを使用する代わりに、テンプレート関数を使用します。

template <typename T>
void WorldView::drawVector(const std::vector<T*>& vector)
{
    typename std::vector<T*>::iterator it;
    for ( it = vector.begin() ; it < vector.end(); it++ )
        window->draw(**it);
}

ところで、生のポインタのベクトルは私には疑わしいように見えます。誰がそれらを所有していますか (誰がそれらを作成し、誰がそれらを削除する責任がありますか)? 値のベクトルの使用を検討するか、boost::ptr_vector

于 2012-05-04T09:34:48.510 に答える
2

発生しているエラーはit = vector.begin();forループ内の割り当てから生成されます。iterator問題は、 (it)をconst iterator( )に割り当てようとしていることですvector.begin()constデータ構造の値は反復ごとに変化するため、イテレータを使用してデータ構造を反復処理することはできません。また、イテレータを使用してデータ構造をトラバースする場合は、のoperator !=代わりにを使用する必要がありoperator <ます。

あなたが物事constから削除する場合はうまくいくはずです。const std::vector& vector

お役に立てれば!

于 2012-05-04T09:19:31.983 に答える
1

Composite Design-Patternを模倣しています。

ただし、エラーは次のとおりです。 < を != に置き換えて記述する必要があります。これは、 intではなくイテレータであるためです。

void WorldView::drawBullets()
{
    std::vector<BulletView*>::iterator it;
    for ( it = bullets.begin() ; it != bullets.end(); it++ )
        window->draw(**it);
}

void WorldView::drawCharacters()
{
    std::vector<CharacterView*>::iterator it;
    for ( it = characters.begin() ; it != characters.end(); it++ )
        window->draw(*it);
}
I would like a more generic method using polymorhism which would look something like this:

void WorldView::drawVector(const std::vector<sf::Drawable*>& vector)
{
    std::vector<sf::Drawable*>::iterator it;
    for ( it = vector.begin() ; it != vector.end(); it++ )
        window->draw(**it);
}
于 2012-05-04T09:04:56.277 に答える