Thread: Abstract classes and iterators

  1. #1
    Registered User
    Join Date
    Mar 2010
    Posts
    20

    Abstract classes and iterators

    I am making a game entity class for a 2d allegro game of mine.
    The abstract class will be entity .. the subclasses will be player, map_blocks and items

    The main reason I am using it is to have an iterator to draw all objects wether it be player .. item or map_block (as in the blocks the player can collide into)

    I am a little unsure about the implementation

    Code:
    virtual void draw(BITMAP *bmp)=0; // this is the abstract function in the entity class
    Code:
    void draw(BITMAP *bmp); // overriding function in player class..draw the player


    How do I setup the iterator, or should i say for loop though?

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    Are you going to have several entities each containing one thing in the game's picture, or is there going to be one entity containing everything about the game's picture? Depending on your answer, you may not need an iterator at all. If you have lots of different entity objects it's more manageable to use the container classes to get iterators.

  3. #3
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    You could use a smart pointer based on the abstract class (boost::shared_ptr maybe) and then fill a std::vector with with these pointers, each one pointing to a player, block or whatever. Then loop through using the std::vector's iterator and call the virtual function on each pointer

  4. #4
    Registered User
    Join Date
    Mar 2010
    Posts
    20
    Many entities.. several map blocks.. several items... 2 players most likely

    By iterator I mean for loop :/ ... think I used the wrong term there.

    Assuming I have an abstract class entity with a draw function and 2 subclasses, player and item, with draw functions..how would I call the draw function for both in the same for loop?

  5. #5
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    Code:
    #include <iostream>
    #include <vector>
    #include <boost/shared_ptr.hpp>
    
    class IBase{
    public:
    	virtual void Draw() = 0;
    };
    
    class Person : public IBase{
    public:
    	virtual void Draw(){
    		std::cout << "I am a person" << std::endl;
    	}
    };
    
    class Enemy : public IBase{
    public:
    	virtual void Draw(){
    		std::cout << "I am an enemy" << std::endl;
    	}
    };
    
    int main(){
    	typedef boost::shared_ptr<IBase> ObjectPtr;
    	typedef std::vector<ObjectPtr> ObjectList;
    
    	ObjectList objects;
    	objects.push_back(ObjectPtr(new Enemy)); 
    	objects.push_back(ObjectPtr(new Person));
    	objects.push_back(ObjectPtr(new Enemy));
    
    	for(ObjectList::iterator i = objects.begin();i != objects.end(); ++i){
    		(*i)->Draw();
    	}	
    }
    That's using boost for shared pointers, but you should get the general idea.

  6. #6
    Registered User
    Join Date
    Mar 2010
    Posts
    20
    I think I got the general idea but I am still getting errors


    in main
    Code:
    	Entity entities[2];
    	entities[0] = new Map;
    	entities[1] = new Player;
    In my player class header file
    Code:
    class Player: public Entity
    {
    	public:
    		Player();
    		void playerMove(); // check for movement
    		void draw(BITMAP *bmp); // draw the player
    };

    but I keep getting these errors
    1> c:\users\jux\documents\visual studio 2008\projects\allegroline\allegroline\Entity.h(10) : see declaration of 'Entity::draw'
    1>.\Allegro_Main.cpp(12) : error C2259: 'Map' : cannot instantiate abstract class
    1> due to following members:
    1> 'void Entity::draw(void)' : is abstract
    1> c:\users\jux\documents\visual studio 2008\projects\allegroline\allegroline\Entity.h(10) : see declaration of 'Entity::draw'
    1>.\Allegro_Main.cpp(12) : error C2679: binary '=' : no operator found which takes a right-hand operand of type 'Map *' (or there is no acceptable conversion)
    1> c:\users\jux\documents\visual studio 2008\projects\allegroline\allegroline\Entity.h(11) : could be 'Entity &Entity:perator =(const Entity &)'
    1> while trying to match the argument list '(Entity, Map *)'
    1>.\Allegro_Main.cpp(13) : error C2259: 'Player' : cannot instantiate abstract class
    1> due to following members:
    1> 'void Entity::draw(void)' : is abstract
    1> c:\users\jux\documents\visual studio 2008\projects\allegroline\allegroline\Entity.h(10) : see declaration of 'Entity::draw'
    1>.\Allegro_Main.cpp(13) : error C2679: binary '=' : no operator found which takes a right-hand operand of type 'Player *' (or there is no acceptable conversion)
    1> c:\users\jux\documents\visual studio 2008\projects\allegroline\allegroline\Entity.h(11) : could be 'Entity &Entity:perator =(const Entity &)'
    1> while trying to match the argument list '(Entity, Player *)'

  7. #7
    &TH of undefined behavior Fordy's Avatar
    Join Date
    Aug 2001
    Posts
    5,793
    >>Entity entities[2];

    You need to work with base pointers as Entity is an abstract class so cannot be instantiated in its own right

  8. #8
    Registered User
    Join Date
    Mar 2010
    Posts
    20
    so I changed some of the code

    Code:
    	Entity *entities[2];
    	entities[0] = new Player;
    	entities[1] = new Map;
    I added all the main classes to entity as virtual

    Code:
    		entities[0]->draw(screenBuffer);//draw the player and check for movement
    		entities[0]->playerMove();
    which works fine for functions that are over riding the abstract class .. but If I use an original function for player or items in main it spits out an error.. i.e any function not listed in the abstract class aswell

    how Do I call original functions?

  9. #9
    Registered User
    Join Date
    Mar 2010
    Posts
    20
    Do I just use the abstract class header file as the mass blueprint with prototype functions for all subclasses and have the implementation in each subclass?
    Basically I have a load of empty functions in my abstract class at the moment, which is working.

    Or is that not the way to do it?
    Last edited by TenTierHook; 11-05-2010 at 03:34 AM.

  10. #10
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,613
    The reason you have abstract classes is to be a sort of blueprint. Commonly its children will implement the base methods in a unique way.

    You can have derived classes with their own methods not from the base class.

    The way to access those would be to reinterpret the base pointer as a pointer to the derived type. So for example

    Code:
    vector<IBase*> objects;
    ....
    Enemy *p = dynamic_cast<Enemy*>(vector[i]);
    p->PlayersDoThis();
    IIRC it's called dynamic binding, and for that to work you have to know exactly what the IBase* is pointing at.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Vectors in vectors - pointers and iterators
    By fisherking in forum C++ Programming
    Replies: 8
    Last Post: 07-27-2010, 09:34 AM
  2. Cannot declare STL iterators in custom templated classes!
    By Maelstrom in forum C++ Programming
    Replies: 8
    Last Post: 03-03-2006, 07:58 PM
  3. im extreamly new help
    By rigo305 in forum C++ Programming
    Replies: 27
    Last Post: 04-23-2004, 11:22 PM
  4. Prime Number Generator... Help !?!!
    By Halo in forum C++ Programming
    Replies: 9
    Last Post: 10-20-2003, 07:26 PM
  5. include question
    By Wanted420 in forum C++ Programming
    Replies: 8
    Last Post: 10-17-2003, 03:49 AM