Skip to main content
GameDev.net gamedev.net
🔒 Locked

differnt types in c++ map

Started by sfx81 Jul 5, 2012 at 3:30 PM 6 replies 2k views
Original Post
sfx81
sfx81
Hi All,
At runtime, if I have 3 classes A, B , C, which do not have any common base class. On network I get strings "A", "B", "C". I want to create instances of these classes based on strings. e.g "A" should create instance of class A. Is there any way to generalize class instances based on "strings" ?
Ideally Id like to have map, e.g map["A"] should return type A instance, and map["B"] should return type B instance.

Thanks in advance.
Caz.
DZee
DZee
Actually the map is the most prone way of dealing with your problem in C++ since it doesn't support reflection like in Java.

I'm not going to provide an example since this subject is rather well-known. This should help you answer all of your questions:
http://stackoverflow...heir-class-name
[size=1]I "surf" the web, literally.
Servant of the Lord
Servant of the Lord
They should have a common base class, if they are related and used in a consistent way. If they aren't used in a consistent way or aren't related, could you give a bit more info on what the purpose is, and what problem you are solving? There may be an entirely different solution that better suits your problem, rather than tricking different class types into a single map.

If classes aren't related, they probably shouldn't be treated as the same.

Depending on your problem, you might consider something like having a class that handles just the common parts between your three classes, and A, B, and C classes contain (through composition) this interface or proxy class. Then you can just add A, B, and C's composition class to the map instead of A,B, and C itself.

But really, what do your three (or however many) classes look like (show their interface code, if possible)? What is their purpose? Are they trying to do too much in a single class?
Why do you need to have them in a std::map, and how are you planning to use that map?
Bregma
Bregma
It sounds to me like you want a factory function that will create objects based on the string passed over the network, not a map that will return already-created objects?
Stephen M. Webb
Professional Free Software Developer
sfx81
sfx81
Hi all,
here is the code I am looking at.


void FillInDataTypes(IXMLtypeData& pData, const String& rstrDataType, const String& rstrPlaceHolder)
{

// IXMLtypeData::Get_dataType(); // This identifies which data type to use

// IXMLtypeData::Get_placeholder(); // this defines subtype of a data type.
// This could be complex or simple. A simple data type is just a pod value with unit as string
// a complex data type will contain one or more comples or simple data types.


// if data type is Flight Level
if ( pData->Get_dataType() == "FlightLevel" )
{
IXMLtypeFlightLevel fl = pData->Get_FlightLevel();
if ( pData->Get_placeholder() == "[altitude]" )
{
// Get unit for level
IXMLSiLevel siLevel = fl->Get_SILevel();
// TODO : plug in unit converter here.
// depending on data elements, setup units
siLevel->Set_unit("feet");
siLevel->Set_value(112);
siLevel->Set_step(100);
}
else if () // for other kind of level
{}
else if () // for other kind of level
{}

}
// if data type is speed
else if ( pData->Get_dataType() == "Speed" )
{
IXMLtypeSpeed speed = pData->Get_Speed();
// get type of speed
if ( pData->Get_placeholder()=="mach" )
{
// get unit for speed
_di_IXMLMachSpeed machSpeed = speed->Get_MachSpeed();
machSpeed->Set_unit("mach");
machSpeed->Set_value(2.0);
}
else if() // for ground speed
{}
else if () // for air speed
{}
}
else if () // for direction
{}
else if () // for position
{}
else if() // for vertical rate
{}
...
}


As you can see there are couple of different data types, with if - elseif switches. I was wondering if it could be easily generalized without doing if - elseif. All it does is, look for a data type, once specific data type is found, look for any specific subtype, untill a simple type is found. Once a simple type is found, fill up the unit and value.
Any idea as to which design pattern would be use full for it ?

Thanks in advance.
Codarki
Codarki
I'm still unsure what you want to do and what is the problem. You are modifying and storing the results back in pData.

Or do you want to return the result some other way? If so, I would just directly create an object and set all the new instances to it, without any type erasure. If you want to erase the concrete type (and treat it through some base), then I have a feeling you'll have to figure out the real type afterwards anyway. You might want to think if you can write generic templates for some of that.
NightCreature83
NightCreature83
All you really want is a static factory function in each object that can be created at runtime for that particular class. This is then stored in a map from string -> callback, and you can then find the creation function based on the name.

The following code implements this and some home brew RTTI implementation which I only added for completeness to the registrar class.
http://code.google.com/p/dxengine/source/browse/trunk/src/ClassRegistration.h
http://code.google.com/p/dxengine/source/browse/trunk/src/RTTI.h
http://code.google.com/p/dxengine/source/browse/trunk/src/RTTIMacros.inl
And this object code shows you how it is used:
http://code.google.com/p/dxengine/source/browse/trunk/src/Object.h
http://code.google.com/p/dxengine/source/browse/trunk/src/Object.cpp

If you forget to add the implement it will cause a compile error.
sfx81
sfx81
Thanks all for responses. I think factory pattern is the way to go.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.