Sign in to follow this  
andyb716

whats the use of STL?

Recommended Posts

SiCrane    11839
The standard template library contains common data structures and algorithms for use in C++ programs. If you need to, for example, a sort a range, you can just use std::sort(). Your favorite C++ reference should be able to provide a comprehensive list of components supplied by the STL.

Share this post


Link to post
Share on other sites
Sandman    2210
It saves the developer from reinventing the wheel. It's full of useful data structures and algorithms, like linked lists, vectors, strings, hash tables, along with sorting algorithms and so on.

Rather than roll your own bug-ridden linked list and a crappy bubble sort, you can just use std::lists and their built in sort functionality. It's pretty fast, it's (mostly) bug free, and you don't have to bother coding it yourself.

Share this post


Link to post
Share on other sites
Sandman    2210
It's all contained in the header files, so there's no libraries to link to.

As for ease of use... you might want to get a book or find some tutorials on the subject. There's lots of functionality in the STL, and the syntax might seem a bit unusual at first. It's also quite important to know about all the components on offer so you can choose the best tool for the job - if you use an stl vector when a list would be better suited, for example, your performance and memory usage could suffer considerably.

Share this post


Link to post
Share on other sites
As guys abopve wrote - you should use it properly but itself is very easy to use.

for example


#include <vector> // header for 'std::vector'

...

void test(void)
{
std::vector<int> test_vector; // declare STL vector with int elements - it's like an array, except that you can set its size

test_vector.resize(10); // set size to 10 element

for(usnigned int i=0; i<10; i++) // fill in
test_vector[i] = i;

test_vector.resize(5); // decrease size to 5 elements

for(usnigned int i=0; i<test_vector.size(); i++) // iterate thru element and print them
printf("%d ", test_vector[i] );
}


output will be: 0 1 2 3 4
...

Share this post


Link to post
Share on other sites


You can do such a resizable array with new[] and delete[].
But vector is superior - not olnly is easier to use but it protects you from having memory leaks in your program - you won't forget to call delete because there's no need to do it.

And last thing - STL includes containers like vector and a bunch of alghoritms that can do many things 'for you'

Share this post


Link to post
Share on other sites
Wildfire    154
Quote:
Original post by tomek_zielinski
you won't forget to call delete because there's no need to do it.

Unless you use it to store pointers

andyb716: The STL is there to give you a bunch of 'standard' libraries that are very well tested and usefull in most any application. You can either go and be the Nth person to eg. write a linked list or use std::list instead. Unless you really need something special, the STL will usually do the job just fine.

Share this post


Link to post
Share on other sites
andyb716    100
thanks for your comments. Is there a really good place to find tutorials. I searched google and a bunch came up and I don't what one to look at.

Share this post


Link to post
Share on other sites
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[i].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!!

Share this post


Link to post
Share on other sites
daviangel    604
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[i] << 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[i] << 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[i] << 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 vector

using 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[i] << 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[i] << 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[i] << 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]

Share this post


Link to post
Share on other sites
Pxtl    354
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Pxtl    354
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.

Share this post


Link to post
Share on other sites
Sneftel    1788
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.

Share this post


Link to post
Share on other sites
Pxtl    354
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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!!

Share this post


Link to post
Share on other sites
snk_kid    1312
Quote:
Original post by graveyard filla
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!!


Aggregation is a special form of association that specifies a whole-part relationship between the aggregate (the whole) and the a component (the part). An example of this would be a car type, and car engine type, the car is the whole and a car engine is a part of the car you would say "car has-a engine". This would mean that car has an instance of engine and not a pointer/reference to one which would be an association relationship or "car knows-a engine".

Forwarding functions i think he mean't delegation which means passing/forwarding a message/request to a component to preform an operation on behalf of it. Takening the car & engine example, you may have an operation in car that allows you add fuel to the car but it's really a wrap to a call to an engine instance to do the real adding fuel because the engine knows how to e.g.


class engine {
public:
void add_fuel(float) {/* yada yada */}
};

class car {
engine _eng;
public:
car(): _eng() {}

void add_fuel(float amount) {
_eng.add_fuel(amount); //delegate the request
}
};


I think by inheritance abuse he means when you do something silly like say have car extend from engine to use it's features or he means ridiclious levels of inheritance say more than 4 levels deep. Aggregation/association & delegation is prefered over inheritance only use inheritance where it makes sense.

It's best to think about types, interfaces/behaviours, various kinds of relationships among types and not to think about implementation to much until you actually do implement.

Weather or not your example code was sloppy sorry i didn't have look at it.

EDIT: callbacks & virtual functions are also a form of delegation, C# has a feature called delegates which you can think of as smart function pointers (i think).

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this