Making items in a set do stuff

This is a discussion on Making items in a set do stuff within the C++ Programming forums, part of the General Programming Boards category; Take a look:
Code:
set<Circle*>* circles = new set<Circle*>() ;
for(int i=0; i<100; i++)
circles->insert(new Circle(rand()%screen_width, rand()%screen_height ));
set<Circle*>::iterator pos;
...

You need two indirections, one for the iterator and one for the pointer.

Code:

(*pos)->draw(buffer);

You can also use algorithms if you want to perform the same action on all objects in the container.

Do you have a particular reason for dynamically allocating the set or for holding pointers rather than objects inside it? In both cases you should generally use regular objects unless you have a specific reason to do otherwise.

You need two indirections, one for the iterator and one for the pointer.

Code:

(*pos)->draw(buffer);

You can also use algorithms if you want to perform the same action on all objects in the container.

Do you have a particular reason for dynamically allocating the set or for holding pointers rather than objects inside it? In both cases you should generally use regular objects unless you have a specific reason to do otherwise.

So, I really have no reason to use pointers to objects here? Should I only do it when passing into functions and stuff?

There is practically never any reason to allocate STL containers themselves dynamically.

The contents of containers are dynamically allocated if you need polymorphism (if your set might also contain sub-classes of Circle's) or if the objects are too expensive or otherwise difficult or impossible to copy.

By the way, as you don't apparently provide any special comparison function, the use of set is quite questionable. The items are ordered according to pointer addresses. Therefore the ordering will be quite random from your perspective (e.g the order in which objects were allocated) and the set won't filter out equivalent objects (because all pointers will be unique), so you might just use a vector instead? (And if it weren't so, and not all allocated objects were actually inserted into the set, you'd leak that memory.)

>> So, I really have no reason to use pointers to objects here? Should I only do it when passing into functions and stuff?

Even passing to functions doesn't really require pointers. If you don't want to pass a copy for efficiency reasons (for example, it is probably best not to copy a full set of objects) then pass a reference to const:

Code:

void drawCircles(const std::set<Circle>& drawableCircles);

If you don't want to pass a copy because you want the actual object to be modified, then pass a plain reference:

Code:

void addDrawableCircles(std::set<Circle>& drawableCircles);

As anon pointed out there are good reasons to use pointers in containers (like for polymorphism or non-copyable objects). There are usually better solutions than using raw pointers there as well, but raw pointers are fine if you have an obvious way of cleaning them up at the right time.

>> What would be the easiest way to pass in a comparator?
It would be easier for you to show your attempt, can you post that and the errors you got? I just recently gave an example of a struct that you can search for if you have found an example already.

Leave the const in, it means that the function doesn't change the state of the struct (which is obviously true since the struct has no state).

Look at the difference between the declaration of the circles pointer (it is set<Circle*,circlecomparator>) and the type you pass to new (which is a set<Circle*>). They should be the same. Of course, since you probably don't need new here you can just do this:

Code:

set<Circle*,circlecomparator> circles;

One other issue with your comparison function is that it returns true for equal. Compare functions should provide a strict weak ordering, which includes the rule that a == b if and only if !(a.compare(b)) && !(b.compare(a)). Use > instead of >= to solve that.

It would be easiest if you could use the default comparison function, that is the operator<. Note that pointers can be compared with < but most likely it is not what you need.

If you need to use a different comparison function / function object, typedef's can help (because the set would otherwise have very long template arguments. With a user-defined function it might look like this: