6

背景信息:我和几个朋友在 och sfml 和 box2d 的帮助下用 C++ 构建这个平台游戏以完成学校作业。要求之一是我们遵循“MVC 模式”。

我们为模型创建了像 Bullet 和 Character 这样的类。BulletView 和 CharacterView(都继承了抽象类 sf::Drawable)用于视图。

而不是复制代码进行绘图并有两个方法 drawBullets 和 drawCharacter 这样

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 测试\sfml 测试\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 测试\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迭代,因为它的值在每次迭代时都会发生变化。此外,在使用迭代器遍历数据结构时,您应该使用 theoperator !=而不是operator <.

如果您constconst std::vector& vector事物中删除它们应该可以正常工作。

希望这可以帮助!

于 2012-05-04T09:19:31.983 回答
1

您正在模仿Composite Design-Pattern

但是你的错误是:你应该写替换 < by !=因为它是一个迭代器而不是一个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 回答