Background info: Me and a couple of friends are building this platform game in C++ with the help och sfml and box2d for a school assignment. One of the requirements is that we follow the "MVC pattern".
We have created classes like Bullet and Character for the model. And BulletView and CharacterView (both inherits sf::Drawable which is an abstract class) for the view.
Instead of duplicating code for drawing and have two methods drawBullets and drawCharacter like this
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);
}
The bulletView vector is declared like this:
std::vector<BulletView*> bullets;
Can't get this to work though. And I'm kind of new to C++ so please have mercy! I've tried searching but have not found very specific answers.
Errors I get while compiling.
Error 8 error C2679: binary '=' : no operator found which takes a right-hand >operand of type 'std::_Vector_const_iterator<_Myvec>' (or there is no acceptable >conversion) c:\users\niklas\multiplaya\sfml test\sfml test\view\worldview.cpp 409 >1 SFML_Test
Error 7 error C2664: 'mp::WorldView::drawVector' : cannot convert parameter 1 from >'std::vector<_Ty>' to 'const std::vector<_Ty> &' c:\users\niklas\multiplaya\sfml >test\sfml test\view\worldview.cpp 402 1 SFML_Test
The problem is that the polimorphism doesn't work at the level of the vectors, but at the levevel of the pointers they contain. So std::vector<Derived*>
can never be passed as an std::vector<Base*>
, since they are completely different types. However, you can fill an std::vector<Base*>
with pointers to Derived*
.
So, you should declare your bullet vector as
std::vector<Drawable*> bullets;
and fill it with BulletView*
, for example:
bullets.push_back( new BulletView( some args) );
drawVector(bullets);
Note: In the code above I am sidestepping the issue of dynamically allocated object ownership. Obviously some mechanism must be in place for deleting the BulletViews
at the right moment.
Instead of using polymorphic vectors, use template function:
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);
}
By the way - vectors of raw pointers look suspicious to me. Who owns them (who creates them and who is responsible to delete them)? Consider using vectors of values or boost::ptr_vector
There errors you're getting are produced from the assignment it = vector.begin();
in your for
loop. The problem is you're trying to assign the iterator
(it
) to const iterator
(vector.begin()
). You can't iterate over a data structure with a const
iterator, because its value changes on each iteration. Also when traversing a data structure using iterators you should use the operator !=
instead of operator <
.
If you remove the const
from const std::vector& vector
things should work just fine.
Hope this helps!
You are imitating the Composite Design-Pattern.
However your error is: you should write replacing < by != because it is an iterator not an 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);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With