Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Dynamic Class Loading

Reply
Thread Tools

Dynamic Class Loading

 
 
Aguilar, James
Guest
Posts: n/a
 
      07-14-2004
My previous example used the concept of a Shape class heirarchy, so I will
continue with that.

Suppose I have something like fifty different shapes, and I am trying to
instantiate one of them. The trick is, the instatiation will be based on a
string with the exact same name as the type that I am trying to instantiate.
Obviously, writing a fifty element long switch statement is an inferior
solution. So, how can I instantiate based on strings? Is there a method
provided in the standard, or am I up a creek without a paddle?


 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      07-14-2004
Aguilar, James wrote:
> My previous example used the concept of a Shape class heirarchy, so I will
> continue with that.
>
> Suppose I have something like fifty different shapes, and I am trying to
> instantiate one of them. The trick is, the instatiation will be based on a
> string with the exact same name as the type that I am trying to instantiate.


The name of a type only exists in the source code. Once the code has
been compiled and linked, there are no type names, and often there are
no distinguishable types either. Just a bunch of functions and const
data that control the behaviour of the program until the run-time data
come in.

> Obviously, writing a fifty element long switch statement is an inferior
> solution.


It's the only solution, AFA C++ is concerned. Variations on the theme
include tables, maps, etc., but essentially they lead to the same task:
association of a string with some function that causes the instantiation
of the corresponding class or classes.

> So, how can I instantiate based on strings? Is there a method
> provided in the standard, or am I up a creek without a paddle?


No method is provided in the language to associate strings with any
types unless you do it yourself. Do not call simple programming task
"up a creek without a paddle". Free cheese exists only in a mousetrap.

V
 
Reply With Quote
 
 
 
 
Phlip
Guest
Posts: n/a
 
      07-14-2004
Aguilar, James wrote:

> My previous example used the concept of a Shape class heirarchy, so I will
> continue with that.
>
> Suppose I have something like fifty different shapes, and I am trying to
> instantiate one of them. The trick is, the instatiation will be based on

a
> string with the exact same name as the type that I am trying to

instantiate.
> Obviously, writing a fifty element long switch statement is an inferior
> solution. So, how can I instantiate based on strings? Is there a method
> provided in the standard, or am I up a creek without a paddle?


Read /Design Patterns/, and use either Prototype, Class Factory, or Factory
Method.

Also, why do you need an instance? Does each class really have state? Could
you use Flyweight?

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces


 
Reply With Quote
 
Aguilar, James
Guest
Posts: n/a
 
      07-14-2004

"Victor Bazarov" <> wrote in message
news:jIdJc.2071$...
> Aguilar, James wrote:
> [snip]


OK, so there's no language construct that lets me do that. The second best
idea is a HashMap, I guess, with the string and the class. However, as you
said, there is no way to represent simply a type in C++. So what should I
put as the data in the hashmap? A pointer to a constructor? I don't think
that works, does it? So, a pointer to a static member method? Something
like this:

//In Something.h
class Something : public Foo
{
public:
void method1();
Something(int n);
static Something* initThis(int n);
}

//In Something.cpp
static Something* Something::initThis(int n)
{
return new Something(n);
}

//In the method that fills the hashmap when the program runs
void fillHashMap()
{
...
map.put("Something", (Something::initThis));
...
//This assumes map is a template of type <string, Something* (*)(int n)>
}

//Then, to get the method that would instantiate Something:
void someothermethod(string classToGet)
{
Something* (initFun*)(int n) = map.get(classToGet);
}

That code would work, right? (Something::initThis)(int n) would resolve to
a pointer to that method, unless I've got my syntax wrong. Please correct
me if I don't have it right.


 
Reply With Quote
 
Aguilar, James
Guest
Posts: n/a
 
      07-14-2004
"Phlip" <> wrote in message
news:93eJc.1808$ m...
> Aguilar, James wrote:
>
> Also, why do you need an instance? Does each class really have state?

Could
> you use Flyweight?


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.

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.


 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      07-14-2004
Aguilar, James wrote:
> "Victor Bazarov" <> wrote in message
> news:jIdJc.2071$...
>
>>Aguilar, James wrote:
>>[snip]

>
>
> OK, so there's no language construct that lets me do that. The second best
> idea is a HashMap, I guess, with the string and the class. However, as you
> said, there is no way to represent simply a type in C++. So what should I
> put as the data in the hashmap? A pointer to a constructor? I don't think
> that works, does it? So, a pointer to a static member method? Something
> like this:
>
> //In Something.h

[...]
>
> That code would work, right? (Something::initThis)(int n) would resolve to
> a pointer to that method, unless I've got my syntax wrong. Please correct
> me if I don't have it right.


That's all fine. The problem is that as soon as you need to do the real
work, you will realise that suddenly all types have to be derived from
that 'Something' class, and that all their "factory methods" (yes, that's
what it's called, it's an idiom) should return the same base pointer and
accept the same arguments. Can your fifty classes handle that? If yes,
good. If not, you will have to do more dancing around to allow your code
to go through the same needle eye to be instantiated.

Go ahead and implement a simple instantiation mechanism for mere two
classes, and you will see what I mean. Then add the third class. If you
do it right, you won't have to do anything except extending the part where
you fill up that HashMap (or whatever).

V
 
Reply With Quote
 
Phlip
Guest
Posts: n/a
 
      07-14-2004
Aguilar, James wrote:

> 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.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces








 
Reply With Quote
 
Aguilar, James
Guest
Posts: n/a
 
      07-14-2004
"Phlip" <> wrote in message
news:HciJc.487$. ..
> Aguilar, James wrote:
>
> 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.


Hahaha, I'm sorry for being confusing. I'm not actually using shapes, that
was just an example. I'm actually trying to design a well typed, object
oriented roguelike game. It is something of a toy project, except for
actually defining the behavior of the game, and some issues of pathing and
map making. Of course, it makes it easier that I don't plan to publish the
game unless I make a lot more progress in the 1.5 months before school
starts than I believe I will now. The issue at hand, in any case, was the
vast numbers of monsters and items that will have to be created, some
randomly, and some from save files.

I think I decided once I realized that you could serialize C++ objects that
I was going to use that method for saving things. However, random monster
generation still needed to be looked into.

> [snip]


That article you sent was interesting and useful. I had thought about
making some static method that would cascade up the class heirarchy, but
this is a better solution, especially since the class heirarchy in my case
could be some three or four layers deep (assuming I get that far).


 
Reply With Quote
 
Phlip
Guest
Posts: n/a
 
      07-14-2004
Aguilar, James wrote:

> Phlip wrote:


> > 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.

>
> Hahaha, I'm sorry for being confusing. I'm not actually using shapes,

that
> was just an example. I'm actually trying to design a well typed, object
> oriented roguelike game. It is something of a toy project, except for
> actually defining the behavior of the game, and some issues of pathing and
> map making. Of course, it makes it easier that I don't plan to publish

the
> game unless I make a lot more progress in the 1.5 months before school
> starts than I believe I will now. The issue at hand, in any case, was the
> vast numbers of monsters and items that will have to be created, some
> randomly, and some from save files.


Hahaha one of my background projects is a game canvas for rogue-like games,
using the TkCanvas. In Ruby.

Writing entire apps in other languages will make you a better programmer,
including a better C++ programmer.

> That article you sent was interesting and useful. I had thought about
> making some static method that would cascade up the class heirarchy, but
> this is a better solution, especially since the class heirarchy in my case
> could be some three or four layers deep (assuming I get that far).


Why are you generating zillions of classes instead of zillions of objects?

The last time I finished a rogue-like game, I gave each monster a pointer to
a function called "brain". That permitted me to change monstrous behavior
without creating a zillion different monster classes.

--
Phlip
http://industrialxp.org/community/bi...UserInterfaces


 
Reply With Quote
 
Aguilar, James
Guest
Posts: n/a
 
      07-15-2004

"Phlip" <> wrote in message
news:e7jJc.494$.. .
> Hahaha one of my background projects is a game canvas for rogue-like

games,
> using the TkCanvas. In Ruby.
>
> Writing entire apps in other languages will make you a better programmer,
> including a better C++ programmer.


Oh, I think I understand that. This is my first non-trivial app in C++.
I've only been working on the language for about three weeks, so it might
not go well, on the other hand, I am familiar with OO design, since I've
been trained in Java for the past year (my freshman year at college).
However, this will be the first large app I have ever done in any language.

> Why are you generating zillions of classes instead of zillions of objects?
>
> The last time I finished a rogue-like game, I gave each monster a pointer

to
> a function called "brain". That permitted me to change monstrous behavior
> without creating a zillion different monster classes.


Well, monsters will have pointers to brains, however, my design is going to
closely follow Nethack's. That means that most of my monsters will be
special cases. Almost all monsters will do something special. For
instance, green slimes will be able to add a SlimeDeath event to the
GeneralEventQueue, but Geletanous cubes will be able to have a consume item
effect on the DungeonFeature directly below them. Meanwhile, brown slimes
will be able to add a BurnEffect to you if you hit them, and blue slimes
will be able to add a FreezeEffect in the same circumstances.

Different monsters will have different random chances of starting off with
particular sets of items (every monster in the game will have an inventory,
though it will in most cases be empty or almost). Also I want some way to
do what Nethack does with cockatrices (they can stone you by various means),
and other types of very unique monsters that can have myriad and unexpected
effects on the player. To do this, I think I need a class structure.
Nethack does it innumerable cascades of if statements, but I think I can
make it neat by classifying all the different things that can possibly
happen, without too much code bloat, and a definite increase in readability.

[OT]
I know that discussing the actual class structure is off topic here, but I'm
going to do it anyway. There will be three or four main base classes
(DungeonFeature, which includes Monster, Item, and GeographicFeature),
Effect (including Healing, Burning, Freezing, Stoning, etc.), Event
(MonsterTurn, all timers, etc.), and a small number of utility classes for
making everything work together (including the main driver, the MapGrid, the
TermInterface, EventQueue, GlobalData, etc.). In this paradigm, I think
that, rather than special casing the types of monsters that would have
special attributes associated, it would be easier just to make a new type
for every _type_ of monster and have monsters that have no special
functionality inherit everything but their stats from their superclass.
[/OT]

Once again, thanks for the advice.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Dynamic loading of .class files and deserializing of object Goofball Java 1 06-11-2007 06:27 PM
Scatter/Gather in Java or Javascript & html (Dynamic class loading?) Richard Maher Java 16 02-20-2007 04:26 PM
cocoon + dynamic class loading Denis Nikiforov Java 1 03-18-2006 05:42 PM
Nested Class, Member Class, Inner Class, Local Class, Anonymous Class E11 Java 1 10-12-2005 03:34 PM
Dynamic class loading problem ... biomechanism Java 7 05-24-2004 03:26 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57