2012-05-04 10 views
4

背景情報: 私と2人の友人が、C++でこのプラットフォームゲームを作成しています。これは、och sfmlとbox2dを学校に割り当てるためです。 要件の1つは、「MVCパターン」に従うことです。C++ベクトル抽象クラスを反復する

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

代わりの描画のためのコードを複製し、この

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); 
} 

のような二つの方法のdrawBulletsとdrawCharacterを持っている私はこのようになりますpolymorhismを使用して、より汎用的な方法をしたいと思います:

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; 

Canしかし、これは動作するようにしないでください。そして私はC++の新機能ですので、慈悲を持ってください!私は検索しようとしましたが、非常に具体的な回答は見つかりませんでした。

エラーコンパイル中にエラーが発生します。

エラー8エラーC2679:バイナリ '=':なしオペレータはタイプの右>オペランド 'STD :: _ Vector_const_iterator < _Myvec>' をとる(または全く許容される>変換がない)cがどの見つかりません:\ \ niklas \ multiplaya \ sfmlテスト\ sfmlテスト\ view \ worldview.cpp 409> 1 SFML_Test

エラー7エラーC2664: 'mp :: WorldView :: drawVector':> 'std :: 1からパラメータ1を変換できません。ベクトル< _Ty> constのSTD」から '::ベクトル< _Ty> &' はC:\ Users \ユーザーニクラス\ multiplaya \ SFML>テスト\ SFMLテスト\ビュー\のworldview.cpp 402 1 SFML_Test

+0

'std :: vector bullets;'は有効な宣言ではありません:ベクトルのテンプレートタイプは何ですか? – James

+0

@Autopulatedそれは私が修正した書式設定の問題でした。 – juanchopanza

答えて

5

であるため、問題がpolimorphismがで動作しないということですベクトルのレベルではなく、含まれているポインタのレベルです。したがって、std::vector<Derived*>は全く異なるタイプなので、std::vector<Base*>として渡すことはできません。ただし、std::vector<Base*>Derived*へのポインタで記入することができます。

だから、あなたは

std::vector<Drawable*> bullets; 

としてあなたの弾丸ベクトルを宣言する必要があり、例えば、BulletView*でそれを埋める:

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

drawVector(bullets); 

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

+0

Hmm okey。おそらく、単に "GameObjectView"クラスのようなものでsf :: Drawableクラスをサブクラス化することになります。答えをありがとう! –

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); 
} 
+0

ベクトルにはランダムアクセスイテレータがあり、これは 'operator <'と比較することができます –

2

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

constconst std::vector& vectorから削除するとうまくいくはずです。

希望すると便利です。代わりに多型のベクトル、使用テンプレート機能使用の

+0

ありがとう!この問題は、@元府パンサが言ったことのようだ。 –

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