View previous topic :: View next topic |
Author |
Message |
qnx l33t
Joined: 25 Jun 2002 Posts: 638 Location: Göteborg, Sweden
|
Posted: Sat Jun 07, 2003 9:02 am Post subject: C++ problem that should be easy to solove... |
|
|
Hi! I'm playing a bit in C++, just to learn how it works (most pointers and classes).
My "project" is about to be a little world, where everything that exists there comes from the Object class. I have created some classes so far: Object->Alive->Animal and Object->Non-Alive (4 classes altogether).
Also I wrote a simple testing program, that tests the classes and how relation between them works.
The testing program takes 2 strings from user, Code: | string objectType
string instanceName | .
Than it should check out if there exists any class in my class library that fits to string entered by user (objectType) and then create an instance of type objectType that will be called instanceName.
But....it's not as easy as I thought it'd be. Following code shows better what I mean:
Code: | cout << "Which type to create?" << endl
<< "You can choose between Object, Alive, Non-Alive or Animal for now."
<< endl << ">>" ;
string objectType;
cin >> objectType;
cout << "OK. You have choosen object type \"" << objectType
<< "\"." << endl << "Now I will create that object for you." << endl
<< "But first, I have to know how you want your new instance to be called."
<< endl << "Give me a name!"
<< endl << ">>" ;
string instanceName;
cin >> instanceName;
cout << "I will create an object of type \"" << objectType << "\" which"
<< endl << "I will call \"" << instanceName << "\"." << endl
<< "Please wait a second!" << endl;
/* THE PROBLEM!
* Now I want to create an instance of <objectType> which will
* be called <instanceName>. But something like:
objectType instanceName;
* simpely doesn't work! What am I doing wrong?
*/
|
Now please, anyone, help me! I guess it could be solved with pointer fields or something similar. Perhaps templates??
As I'm only C++ n00b, I don't know how to fix it really, but I learn quickly =) Thanks for reading!
Cheers,
Jacob _________________ Registred Linux user #191143!
Abit NF7-S rev. 2.00 (BIOS v. 2.7)
AMD AthlonXP 2500+ (Barton)
PATA Seagate ST3120022A
SATA Seagate ST3200822AS & Silicon Image 3112 chipset
Gentoo Linux |
|
Back to top |
|
|
Braempje l33t
Joined: 31 Jan 2003 Posts: 748
|
Posted: Sat Jun 07, 2003 9:32 am Post subject: |
|
|
Create a (pure virtual) method in the base class, like create, that returns a pointer to the base class. Than have your instance creation program call that method, and store the pointer in instanceName.
(If you're looking for more information on this, you're discovering polymorphism.) _________________ Dictionary of the Flemish Sign Language - Woordenboek Vlaamse Gebarentaal |
|
Back to top |
|
|
far Guru
Joined: 10 Mar 2003 Posts: 394 Location: Stockholm, Sweden
|
Posted: Sat Jun 07, 2003 9:32 am Post subject: |
|
|
I'm sorry, this is simply not possible to do in a statically typed compiled language like C++. Variable definitions have to be made at compile time. The best you can do is something like this:
Code: | Object *object;
if(objectType == "Object")
object = new Object();
else if(objectType == "Alive")
object = new Alive();
else if(objectType == "Animal")
object = new Animal();
else if(objectType == "Non-Alive")
object = new Non-Alive();
else throw runtime_error("unknown object type");
object->set_name(instanceName); |
_________________ The Porthole Portage Frontend
Last edited by far on Sat Jun 07, 2003 9:44 am; edited 1 time in total |
|
Back to top |
|
|
() l33t
Joined: 25 Nov 2002 Posts: 610
|
Posted: Sat Jun 07, 2003 9:40 am Post subject: |
|
|
A factory class is much nicer than manual switch logic :\ You pass it a name and it passes you an object of the correct type (given it knows how to). For an implementation see http://sourceforge.net/projects/loki-lib/. |
|
Back to top |
|
|
far Guru
Joined: 10 Mar 2003 Posts: 394 Location: Stockholm, Sweden
|
Posted: Sat Jun 07, 2003 10:10 am Post subject: |
|
|
() is right, but the source code for Loki might be a little difficult to grasp, especially since I couldn't find any documentation.
If you want to be able to find an object by name you could use map:
Code: | #include <map>
[...]
std::map<std::string, Object*> world_map;
world_map[instance_name] = object; |
_________________ The Porthole Portage Frontend |
|
Back to top |
|
|
biscon n00b
Joined: 27 Apr 2003 Posts: 43
|
Posted: Sat Jun 07, 2003 11:54 am Post subject: ... |
|
|
try googling for RTTI sound like that is what you need |
|
Back to top |
|
|
far Guru
Joined: 10 Mar 2003 Posts: 394 Location: Stockholm, Sweden
|
Posted: Sat Jun 07, 2003 12:12 pm Post subject: |
|
|
RTTI (Run-Time Type Information) is only useful when you have an object and want to determine what type it is. It won't help you create a new instance of an class from a string with its name. Of course, you could have a container with prototype objects with clone() methods that you iterate over and use typeid to get the type name and compare it to your string, but there are more efficient ways of doing that. _________________ The Porthole Portage Frontend |
|
Back to top |
|
|
() l33t
Joined: 25 Nov 2002 Posts: 610
|
Posted: Sat Jun 07, 2003 12:40 pm Post subject: |
|
|
far wrote: | () is right, but the source code for Loki might be a little difficult to grasp, especially since I couldn't find any documentation. |
Thats what the book is for I'm afraid. But it isn't as hard to use as to understand the implementation. Basically it takes several template parameters, but only two are strictly necessary. Say you have a class Abstract, and you use std::string for identification; then you create a factory like this:
Code: |
Loki::Factory<Abstract, std::string> myFactory; |
You would also register a creator function for each type you would want to create:
Code: | Abstract *createDerived() {
return new Derived();
}
myFactory.Register( "Derived", &createDerived );
std::string cls( "Derived" );
Abstract *absObj( myFactory.CreateObject( cls ) ); |
Quite useful methinks. |
|
Back to top |
|
|
qnx l33t
Joined: 25 Jun 2002 Posts: 638 Location: Göteborg, Sweden
|
Posted: Sun Jun 08, 2003 6:15 pm Post subject: |
|
|
All,
Thank you for Your replies. Unfortunately I cannot test them now due to a HARDDISK CRASH (or almost a crash...). Unmountable root partiotion....
For more info please check out: https://forums.gentoo.org/viewtopic.php?t=59187&highlight=&sid=c80471cd200223a64069f2710660d7a3 _________________ Registred Linux user #191143!
Abit NF7-S rev. 2.00 (BIOS v. 2.7)
AMD AthlonXP 2500+ (Barton)
PATA Seagate ST3120022A
SATA Seagate ST3200822AS & Silicon Image 3112 chipset
Gentoo Linux |
|
Back to top |
|
|
enedhilwen n00b
Joined: 09 Apr 2003 Posts: 9 Location: Germany, Munich, Computer
|
Posted: Sun Jun 08, 2003 7:34 pm Post subject: ebuild for loki-lib? |
|
|
Quote: | A factory class is much nicer than manual switch logic :\ You pass it a name and it passes you an object of the correct type (given it knows how to). For an implementation see http://sourceforge.net/projects/loki-lib/. |
What about an ebuild for it? Should I try to make one or is there no need for it?
Ened |
|
Back to top |
|
|
() l33t
Joined: 25 Nov 2002 Posts: 610
|
Posted: Mon Jun 09, 2003 6:44 am Post subject: Re: ebuild for loki-lib? |
|
|
enedhilwen wrote: | Quote: | A factory class is much nicer than manual switch logic :\ You pass it a name and it passes you an object of the correct type (given it knows how to). For an implementation see http://sourceforge.net/projects/loki-lib/. |
What about an ebuild for it? Should I try to make one or is there no need for it?
Ened |
Good idea, Ened. I thought of making one myself, but I haven't got into making ebuilds yet (got enough on my plate as it is). I'm sure others would find it useful too. |
|
Back to top |
|
|
enedhilwen n00b
Joined: 09 Apr 2003 Posts: 9 Location: Germany, Munich, Computer
|
Posted: Mon Jun 09, 2003 8:09 am Post subject: |
|
|
Quote: | Good idea, Ened. I thought of making one myself, but I haven't got into making ebuilds yet (got enough on my plate as it is). I'm sure others would find it useful too. |
Hmm isn't so easy. No Makefile or ./configure-scipt (only plain source code), so how could we integrate it into gentoo?
Shared libraries? What would you say?
Ened |
|
Back to top |
|
|
far Guru
Joined: 10 Mar 2003 Posts: 394 Location: Stockholm, Sweden
|
Posted: Mon Jun 09, 2003 8:31 am Post subject: |
|
|
It is mostly just a bunch of header files. Making a library would be pointless. Also, there is no license attached, so I think the author just expects you to copy the files you like to your project. _________________ The Porthole Portage Frontend |
|
Back to top |
|
|
() l33t
Joined: 25 Nov 2002 Posts: 610
|
Posted: Mon Jun 09, 2003 10:51 am Post subject: |
|
|
I just put it in /usr/include/loki. The only non-header file I think is SmallObj.cpp which some classes rely on. |
|
Back to top |
|
|
qnx l33t
Joined: 25 Jun 2002 Posts: 638 Location: Göteborg, Sweden
|
Posted: Mon Jun 09, 2003 8:17 pm Post subject: |
|
|
far wrote: | I'm sorry, this is simply not possible to do in a statically typed compiled language like C++. Variable definitions have to be made at compile time. The best you can do is something like this:
Code: | Object *object;
if(objectType == "Object")
object = new Object();
else if(objectType == "Alive")
object = new Alive();
else if(objectType == "Animal")
object = new Animal();
else if(objectType == "Non-Alive")
object = new Non-Alive();
else throw runtime_error("unknown object type");
object->set_name(instanceName); |
|
A couple of questiones:
Is it really possible with that if-statment?? Cause, if user wants to create an Animal, then the produced code will be:
Code: |
Object *object;
object = new Animal();
|
and not
Code: |
Animal *object;
object = new Animal();
|
Secondly, "object->set_name(instanceName)". set_name is something I have to write, right?? Or does it exist in C++ already ?! Also, it's not needed anymore, cause I can reach the new instance by *object..... _________________ Registred Linux user #191143!
Abit NF7-S rev. 2.00 (BIOS v. 2.7)
AMD AthlonXP 2500+ (Barton)
PATA Seagate ST3120022A
SATA Seagate ST3200822AS & Silicon Image 3112 chipset
Gentoo Linux |
|
Back to top |
|
|
far Guru
Joined: 10 Mar 2003 Posts: 394 Location: Stockholm, Sweden
|
Posted: Mon Jun 09, 2003 8:30 pm Post subject: |
|
|
Quote: | Is it really possible with that if-statment?? Cause, if user wants to create an Animal, then the produced code will be:
Code: | Object *object;
object = new Animal();
|
|
This is ok, but only if Animal is a subclass of Object.
Quote: | Secondly, "object->set_name(instanceName)". set_name is something I have to write, right?? Or does it exist in C++ already ?! Also, it's not needed anymore, cause I can reach the new instance by *object..... |
Correct. But I assumed that you wanted to create lots of objects dynamically and access them by name, in which case the easiest way would be to use std::map. _________________ The Porthole Portage Frontend |
|
Back to top |
|
|
|