whats the use of STL?

Started by
19 comments, last by snk_kid 19 years, 9 months ago
the real beauty of the STL is, you dont have to keep track of your objects anymore. this can lead to some really nice designs. using OOP, you can abstract your objects, and using a container, you can hide your object even further, to the point where you want a new object, you just do this:

Object *obj = new Object();

object_list.push_back(obj);

its very nice! just keep this in mind while desinging your next game... you dont have to manually track your items, you dont have to care what index that are at, hell, you dont even use index's anymore unless you work with a vector. the best part is, you dont have to know where your object is. all you have to do is register your object with a "master list", then the master list will update your object. for example, using the other ex., just do this in your main loop each frame"

for(int i = 0; < object_list.size(); i++)
object_list.Update();

this will call Update on all your objects! since. what i do is, make Object a fully abstract base class (is this what its called?), where it doesnt do anything, it simply has a virtual void Update() as a member. then, all your objects which need to Update() each frame, you inherit from the Object class. then you can stuff all your objects into a single container (or a vector of containers) and manage all your game objects from one list! the best part is, you dont even have to manage them yourself. simply register them with the list via push_back(), and voila, you have a self-managing object system.

since all your objects will Update() differently, just over-ride the Update() function in all your classes which inherit from Object (or whatever you name the class...). IMO this is the great advantage of C++ and OOP, inheritense, polymorphism, and cotainers... mmmmmmm. if you dont know what Polymorphism is yet, its not very complicated. polymorphism is simply grouping different classes togeather. so you can inherit Enemy from the Object class, and inherit Player from the Object class, and inherit Particle, or Bomb, or Map, or anything you want from the Object class... then you can group your player,enemies,map, bombs, all togeaher, even though they arent the same data type! to do this, you have to use pointers, since you cant directly goup the objects togeather, but you CAN diectly group there pointers togeather , which is just as good.

for managing your objects , since they will be allocated dynamically (a must since you need to use pointers for polymorphism), you could make Update() return bool, intead of void. then, when you want an object to be removed from the world, simpy return false from its Update(). then when you call Update, anyone returning false will be removed from the world. it could be when an enemy dies, or whenever you want an object to be removed. heres an example

inside Object.cpp
class Object{    public:   virtual bool Update() = 0;      private:   static std::list<Object*> world_objects;};



inside Enemy.h / .cpp
class Enemy: public Object{    public:     Enemy(int xpos,int ypos);    virtual bool Update();    void Do_Schtuff();   private:       bool im_dead;};bool Enemy::Update(){      //do anything an enemy does, do AI, move around, collision detection, WHATEVER!   //at the end, we check if we died. if so, return false and remove us from the world - else return true and keep going     if(im_dead)       return false;       else return true;}


now inside your main game loop.....

while(!game_over){//somewhere, whenever you want to add an enemy, you just do  //create an enemy starting at (35,72)  Enemy *new_enemy = new Enemy(35,72);    //register this enemy with the world Object::world_objects.push_back(new_enemy);   //now, each frame, you update your world!!   for(it = Object::world_objects.begin(); it != Objects::world_objects.end()}    {          //update the object, and if he returned false, REMOVE HIM!          if(!(*it)->Update())         {              //delete the memory first              delete *it;              //now remove the object from the world              Object::world_objects.remove(*it);         }         else it++;    }}


do you see whats going on here? anything which needs to be Updated() each frame, inherits from Object. then you have a list of pointers to Objects, ie list<Object*> world_objects. this is your master list of objects! when you want a new being in the world, you register the object with the world, and the world will update it and manage it for you. it will delete the memory for you so no worries about memory leaks.... there might be some syntatical errors, im at work now so i dont have my code in front of me, but this is the gist of it! this is the ideal thing for a std::list, but dont be scared, they work almost exactly the same as a vector does, except you cannot index a list via [x], like with a vector, which is why i used iterators. dont be scared about the iterators either, you will learn them when you learn about the other containers, they are just how you loop through the elements of a container, since you can index a list like you cant a vector (since they arent sequential in memory like an array). like i said, dont be scared about the other types of containers - they are all very much like a vector - and a vector is very much like an array. but each container has its own purpose, and a list is best for this. good luck!!
FTA, my 2D futuristic action MMORPG
Advertisement
Quote:Original post by andyb716
is it easy to use?
do you have to include a bunch a files and link libraries and
set the include directories?

here's a pretty good and simple example from a book I'm reading right now:
not using STL way
// hero's inventory// demonstrate arrays// WARNING:no bounds checking perfomed// compile with c++ -o hero_inventory heros_inventory.cpp#include <iostream>#include <string>using namespace std;int main(){  const int MAX_ITEMS = 10;  string inventory[MAX_ITEMS];  // create array of strings  int numItems = 0;  inventory[numItems++] = "sword";  inventory[numItems++] = "armor";  inventory[numItems++] = "shield";  cout << "Your items:\n";  for(int i = 0; i < numItems; ++i)	cout << inventory << endl;  cout << "\nYou trade your sword for a battle axe.";  inventory[0] = "battle axe";  cout << "\nYour items:\n";  for(int i = 0; i < numItems; ++i)	cout << inventory << endl;  cout << "\nThe item name '" << inventory[0] << "' has ";  cout << inventory[0].size() << " letters in it.\n";  cout << "\nYou find a healing potion.";  if(numItems < MAX_ITEMS)	inventory[numItems++] = "healing potion"; // add item to array  else	cout << "You have too many items and can't carry another.";  cout << "\nYour items:\n";  for(int i = 0; i < numItems; ++i)	cout << inventory << endl;  return 0;}


now the same program using STL
// Hero's inventory 2.0// Demonstrates vectors#include <iostream>#include <string>#include <vector> // needed to use vectorusing namespace std;int main(){  vector<string> inventory;  inventory.push_back("sword");  inventory.push_back("armor");  inventory.push_back("shield");  cout << "You have " << inventory.size() << " items.\n";  cout << "\nYour items:\n";  for(int i = 0; i < inventory.size(); ++i)    cout << inventory << endl;  cout << "\nYou trade your sword for a battle axe.";  inventory[0] = "battle axe";  cout << "\nYour items:\n";  for(int i = 0; i < inventory.size(); ++i)    cout << inventory << endl;  cout << "\nThe item name '" << inventory[0] << "' has ";  cout << inventory[0].size() << " letters in it.\n";  cout << "\nYour shield is destroyed in fierce battle.";  inventory.pop_back();  cout << "\nYour items:\n";  for(int i = 0; i < inventory.size(); ++i)    cout << inventory << endl;  cout << "\nYou were robbed of all of your possessions by a thief.";  inventory.clear();  if(inventory.empty())    cout << "\nYou have nothing.\n";  else    cout << "\nYou have at least one item.\n";  return 0;}

using more STL and iterators
// Hero's inventory 3.0// Demonstrates vectors and iterators using STL#include <iostream>#include <string>#include <vector>using namespace std;int main(){  vector<string> inventory;  inventory.push_back("sword");  inventory.push_back("armor");  inventory.push_back("shield");    vector<string>::iterator myIterator;  vector<string>::const_iterator iter;    cout << "Your items:\n";  for(iter = inventory.begin(); iter != inventory.end(); ++iter)    cout << *iter << endl;	  cout << "\nYou trade your sword for a battle axe.";  myIterator = inventory.begin();  *myIterator = "battle axe";  cout << "Your items:\n";  for(iter = inventory.begin(); iter != inventory.end(); ++iter)    cout << *iter << endl;	  cout << "\nThe item name '" << *myIterator << " ' has ";  cout << (*myIterator).size() << " letters in it.\n";    cout << "\nThe item name '" << *myIterator << " ' has ";  cout << myIterator->size() << " letters in it.\n";    cout << "\nYou recover a crossbow from a slain enemy.";  inventory.insert(inventory.begin(),"crossbow");  cout << "Your items:\n";  for(iter = inventory.begin(); iter != inventory.end(); ++iter)    cout << *iter << endl;	  cout << "\nYour armor is destroyed in a fierce battle.";  inventory.erase((inventory.begin() + 2));  cout << "Your items:\n";  for(iter = inventory.begin(); iter != inventory.end(); ++iter)    cout << *iter << endl;  return 0;}

And one thing you want to watch out for is if you are using VC6.0 you might not be able to compile a lot of STL programs since it's support for STL and the C++ standard is poor.
So I use Visual Studio 2003 now or gcc 3.3 on macosx or linux and don't have any problems.

[Edited by - daviangel on July 8, 2004 2:18:53 PM]
[size="2"]Don't talk about writing games, don't write design docs, don't spend your time on web boards. Sit in your house write 20 games when you complete them you will either want to do it the rest of your life or not * Andre Lamothe
Yep. Good use of STL and similar libraries can make coding C++ as nice as a modern scripting language like Python. My only problem with it is that it doesn't include refcounted smartpointers, and the STL container objects themselves are designed for holding copies, not pointers. So, to the best of my knowledge, you can't have define an STL container for virtual objects. No heterogeneity allowed.
-- Single player is masturbation.
Quote:Original post by Pxtl
Yep. Good use of STL and similar libraries can make coding C++ as nice as a modern scripting language like Python. My only problem with it is that it doesn't include refcounted smartpointers, and the STL container objects themselves are designed for holding copies, not pointers. So, to the best of my knowledge, you can't have define an STL container for virtual objects. No heterogeneity allowed.


im not sure what you mean by heterogenity, but you can certainly have virtual objects in a container. read my above example. you simply just have a container of pointers to a base class.
FTA, my 2D futuristic action MMORPG
Maybe STLPort is, due to its optimizations, not a proper implementation of the STL, but it does not support that feature. If I attempt to put a pure-virtual base class as the class-type of an STL container, it barfs at me during compile time.
-- Single player is masturbation.
Quote:Original post by Pxtl
Maybe STLPort is, due to its optimizations, not a proper implementation of the STL, but it does not support that feature. If I attempt to put a pure-virtual base class as the class-type of an STL container, it barfs at me during compile time.
You're probably trying to put that class type in, rather than pointers to that class. You can, of course, not instantiate abstract classes.
Well, that's my point. Since the STL isnt designed for pointers, then you lose a bunch've the convenience it provides by having to use pointers instead. I realise that it is not realistic to expect a virtual class to be the type of an stl container and then allow other classes to be copied in - that's not realistic. I just wish that there was better designed in capability for polymorphism. Like some sort of auto_ptr that was designed to work with STL containers or something, but the true auto_ptr is not meant for the containers. I've seen many coders run in to this - want to make a polymorphic STL container where removal=destruction, like with normal copies. Can't do that without a lot of coding.
-- Single player is masturbation.
Quote:Original post by Pxtlwant to make a polymorphic STL container where removal=destruction, like with normal copies. Can't do that without a lot of coding.


Define "a lot" it's actually quite easy todo with aggregation and forwarding functions, or if you're sloppy via inheritance abuse.
HardDrop - hard link shell extension."Tread softly because you tread on my dreams" - Yeats
Quote:Original post by Pxtl
Can't do that without a lot of coding.

Or boost::shared_ptr.
Quote:Original post by DigitalDelusion
Define "a lot" it's actually quite easy todo with aggregation and forwarding functions, or if you're sloppy via inheritance abuse.


could you please explain what you mean here? what do you mean by "sloppy inheritense abuse"? would you consider what i posted above in that category? i personally think its very elegant and not sloppy at all, but im a newbie so im not too sure. but it works very well with me for my situation.. flexible and easy to use...

also, if it is or isnt sloppy, could you explain why it is, and what are the alternatives? what is aggregation and forwarding functions? thanks for any help!!
FTA, my 2D futuristic action MMORPG

This topic is closed to new replies.

Advertisement