Can a program user 'name' an inherited object/instance?

Started by
17 comments, last by MikeWhiskyTango 13 years, 9 months ago
I want a program user to make a selection from a list of items and then input a simple individual ID tag ie; A1 or B3 etc at the same time or soon after.
The program then instantiates the object, based on that user's selection (from a host of inherited classes), but importantly the ID tag the user enters must be GIVEN to that instantiated object. Perhaps 'given' is the wrong term? Attached? Whatever term is appropriate, the end result must be that the instantiated instance must have that same input ID entered by the user?
Any ideas how to achieve this?
Advertisement
I don't really understand what you're trying to achieve. Could you please provide a more concrete example that might get us a feel for how you intend to use this?
class BaseClasssWithId{public:    BaseClassWithId(const char* ID)    {        memcpy(m_id, ID, sizof(ID) * numberElementsInID);    }protected:    char* m_id;}


This is psuedo C++ offcourse!

Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2, theHunter, theHunter: Primal, Mad Max, Watch Dogs: Legion

Are you saying that the user must select which of several suclasses to instantiate? Depending on the language, there can be multiple ways to do this. In almost any, you can make a (potentially long) series of if-else if- etc. statements and compare the player input to instantiate the proper subclass. In some languages where classes are first-class (such as Python), you could make a map or dictionary which maps the input type (integer or string, most likely) to a class. Then you can just instantiate the mapped-to class normally.

Also, you might want to explain what the end effect you're trying to achieve is. There might be a better way than this.

Edit: Oh, is that not the part you want help with? If so, I suppose NightCreature's answer might suffice, though it looks like odd C-with-classes more than C++ (why no std::string?). But, the general idea is to give the base class an ID value which can be assigned either in the constructor or in a SetID function.

This, though raises the question of why something must know its own ID. Many times an object should not be responsible for holding its own ID (single responsibility principle and all that). If all you need is to look them up based on IDs, then you can make a map or dictionary which takes an ID as a key and a base class instance as a value.
Lets say there is a list the user can select from. IE: A list of cars. The player in this game selects a Porsche.
In my program each variety of car is an inherited class from Car base class.
The user must then also cin input a code tag, anything, a name, a letter, etc.
The program then creates the chosen object, ie; it instantiates the Porsche.
But I want it to be named based on the cin input from the player.
The program creates the Porsche but I want that particular instance when its created to be named only as per the players input.
IE player selects Posrsche and then is requested to enter a ID and he types in A2. Thus when the porsche is instantiated; Porsche A2; The A2 is thus the name of that particular instance.
I dont know if thats clear as mud still?
(See my edit two posts up.)

What do you want to then do with the name? That makes all the difference in the world.
Thanks nightcreature.
Its basically just to manage my nephews little model car game. Give him some AI. And just to give me another project to learn c++.
I realised that at various times he would have to enter stuff about the cars and people in his 'town', but to do that all I could think of was giving each item an ID tag. Then when things changed in the 'lego town' he could simply enter the ID which he's given to each item (car or person etc). The program would also tell him to do stuff with some of the cars and people etc. Actually kind of fun making the AI.
I couldnt think of any other way apart from him entering a ID tag/name that may change each time he played the game.

Thanks for the code, I shall decipher it tomorrow and see if I can get it to work.
kinda like NightCreature83 but with less to "decipher"

class carBase{      void setId(std::string _id)    { id = _id;  }      std::string getId()            { return id; }protected:      std::string id;}


ps: Ezbez's suggestion with the map is clearly a more convenient solution.
Did you try using C++ STL maps?
Quote:Original post by MikeWhiskyTango
Thanks nightcreature.
Its basically just to manage my nephews little model car game. Give him some AI. And just to give me another project to learn c++.
I realised that at various times he would have to enter stuff about the cars and people in his 'town', but to do that all I could think of was giving each item an ID tag. Then when things changed in the 'lego town' he could simply enter the ID which he's given to each item (car or person etc). The program would also tell him to do stuff with some of the cars and people etc. Actually kind of fun making the AI.
I couldnt think of any other way apart from him entering a ID tag/name that may change each time he played the game.

Thanks for the code, I shall decipher it tomorrow and see if I can get it to work.


This is how I would do this. First, download camp and have a look at the tutorials. Basically camp offers the possibility to create instances at runtime, without you knowing the concrete type. This works by first registering all possible types with camp and the doing stuff like the following:

// retrieving a class by its nameconst camp::Class& metaclass = camp::classByName("MyClass"); // constructing an instance of the classMyClass* object = metaclass.construct<MyClass>(camp::Args(10, 5.f)); // wrapping the C++ instance into a typeless objectcamp::UserObject metaobject = object; // calling an object's function by its namemetaobject.call("func");// reading and writing an objet's property by its namemetaobject.set("prop", 50);int x = metaobject.get("prop");


As you can see, you can easily instantiate a class without knowing it's type. The important thing is that camp::Args is a vector of variants, which means they can (nearly) take any type you want.

Now concerning your example, you might do something similar to this:
std::string carname;std::string arg1, arg2;std::cout &lt;&lt; "Please enter the car you want to instantiate: ";std::cin &gt;&gt; carname;const camp::Class& metaClass = camp::classByName(carname);std::cout &lt;&lt; "Okay, now enter the constructor's arguments";std::cin &gt;&gt; arg1 &gt;&gt; arg2;CarBase* object = metaClass.construct&lt;CarBase&gt;(camp::Args(arg1, arg2));

This is typed right of my mind and only demonstrates what you can do with camp. Please not that using std::cin the way I used it is NOT the recommended way (why?), I just want to write less code.
Camp is very powerful (no I'm not advertising :D) and really suited for that kind of problem. Ideally you would ask the metaclass about the number and types of parameters the constructor requires, however this is currently not implemented in camp (but adding this manually is a matter of one hour at most).

This topic is closed to new replies.

Advertisement