背景资料: 我和几个朋友正在使用帮助och sfml和box2d为学校作业构建这个平台游戏。 其中一个要求是我们遵循“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&lt; _Myvec&gt;'的右手&gt;操作数(或者没有可接受的&gt;转换)c:\ users \ niklas \ multiplaya \ sfml test \ sfml test \ view \ worldview.cpp 409&gt; 1 SFML_Test
错误7错误C2664:'mp :: WorldView :: drawVector':无法从&gt;'std :: vector&lt; _Ty&gt;'转换参数1到'const std :: vector&lt; _Ty&gt; &安培;” c:\ users \ niklas \ multiplaya \ sfml&gt; test \ sfml test \ view \ worldview.cpp 402 1 SFML_Test
答案 0 :(得分:5)
问题在于,多向性不能在向量的层面上起作用,而是在它们包含的指针的层次上。因此,std::vector<Derived*>
永远不能作为std::vector<Base*>
传递,因为它们是完全不同的类型。但是,您可以使用指向std::vector<Base*>
的<{1}}填充Derived*
。
因此,您应该将子弹矢量声明为
std::vector<Drawable*> bullets;
并填充BulletView*
,例如:
bullets.push_back( new BulletView( some args) );
drawVector(bullets);
注意:在上面的代码中,我回避了动态分配对象所有权的问题。显然,必须有适当的机制来在适当的时候删除BulletViews
。
答案 1 :(得分: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
答案 2 :(得分:2)
您的it = vector.begin();
循环中的作业for
会产生错误。问题是您尝试将iterator
(it
)分配给const iterator
(vector.begin()
)。您不能使用const
迭代器迭代数据结构,因为它的值会在每次迭代时更改。此外,在使用迭代器遍历数据结构时,您应该使用operator !=
而不是operator <
。
如果您从const
移除const std::vector& vector
,则应该可以正常使用。
希望这有帮助!
答案 3 :(得分:1)
您正在模仿Composite Design-Pattern。
但是你的错误是:你应该写替换&lt; 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);
}