Well, I'm pretty sure I need instances. Tell me if I'm wrong: there could
be as many as twenty different shapes on the screen at any time, and they
will all have different states. Some will be colored, some not, some will
be of different sizes than the others, and all will contain some kind of
text data too.
To solve your outer problem, I would use a Tk Canvas. You might find a
wrapper for it in C++, or you might use a more programmer-friendly language,
like Ruby or TCL, to drive the canvas.
It does what you need out of the box: Float a bunch of shapes around the
screen. Each shape is an object, so changing its attributes intelligently
updates the screen.
Do you know where I can find information of the type that would be in Design
Patterns on this issue on the internet? I am also going to google for such
information right now, but I find that sometimes people already have in mind
a place to go that would take me a long time to find sorting through google
searches. I will go out and look for the book, but I also need some kind of
solution to the issue in the near term.
I Googled for "stl map c++ factory" without the quotes, and got these on the
first page:
http://www.linuxjournal.com/article.php?sid=3687
---8<----------------
Autoregistration
Loading the maker functions into an array associates a position in the array
with each maker. While this may be useful in some cases, we can obtain more
flexibility using an associative array to hold the makers. The Standard
Template Library (STL) map class works well for this, as we can then assign
key values to the makers and access them via these values. For example, we
may desire to assign string names to each class and use these names to
invoke the appropriate maker. In this case, we can create a map such as
this:
typedef shape *maker_ptr();
map <string, maker_ptr> factory;
Now when we want to create a particular shape, we can invoke the proper
maker using the shape name:
shape *my_shape = factory[
We can extend this technique to make it even more flexible. Rather than
loading the class makers in and explicitly assigning a key value to them,
why not let the class designers do the work for us? Using a little bit of
ingenuity, we can have the makers register themselves with the factory
automatically, using whatever key value the class designer chooses. (There
are a couple of warnings here. The key must be of the same type as all the
other keys, and the key value must be unique.)
One way to accomplish this would be to include a function in each shape
library that registers the maker for us, and then call this function every
time we open a shape library. (According to the dlopen man page, if your
library exports a function called _init, this function will be executed when
the library is opened. This may seem to be the ideal place to register our
maker, but currently the mechanism is broken on Linux systems. The problem
is a conflict with a standard linker object file, crt.o, which exports a
function called _init.) As long as we are consistent with the name of this
function, the mechanism works well. I prefer to forego that approach in
favor of one that will register the maker simply by opening the library.
This approach is known as ``self-registering objects'' and was introduced by
Jim Beveridge (see Resources).
We can create a proxy class used solely to register our maker. The
registration occurs in the constructor for the class, so we need to create
only one instance of the proxy class to register the maker. The prototype
for the class is as follows:
class proxy {
public:
proxy(){
factory["shape name"] = maker;
}
};
Here, we assume factory is a global map exported by the main program. Using
gcc/egcs, we would be required to link with the rdynamic option to force the
main program to export its symbols to the libraries loaded with dlopen.
Next, we declare one instance of the proxy:
proxy p;
Now when we open the library, we pass the RTLD_NOW flag to dlopen, causing p
to be instantiated, thus registering our maker. If we want to create a
circle, we invoke the circle maker like so:
shape *my_circle = factory["circle"];
The autoregistration process is powerful because it allows us to design the
main program without having explicit knowledge of the classes we will
support. For instance, after the main program dynamically loads any shape
libraries, it could create a shape selection menu using all the keys
registered in the factory. Now the user can select ``circle'' from a menu
list, and the program will associate that selection with the proper maker.
The main program does not need any information about the circle class as
long as the class supports the shape API and its maker is properly defined.
----8<------------------
You need to give a prototypical shape a "clone()" method, then put a
prototype into each slot in a map, forming a factory. Any C++ tutorial
should cover clonables.