Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

differnt types in c++ map


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
7 replies to this topic

#1 sfx81   Members   -  Reputation: 131

Like
0Likes
Like

Posted 05 July 2012 - 09:30 AM

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.

#2 DZee   Members   -  Reputation: 194

Like
0Likes
Like

Posted 05 July 2012 - 09:38 AM

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

Edited by DZee, 05 July 2012 - 09:47 AM.

I "surf" the web, literally.


#3 Servant of the Lord   Marketplace Seller   -  Reputation: 8941

Like
1Likes
Like

Posted 05 July 2012 - 09:46 AM

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?

All glory be to the Man at the right hand... On David's throne the King will reign, and the Government will rest upon His shoulders. All the earth will see the salvation of God.

Of Stranger Flames - [indie turn-based rpg set in a para-historical French colony] | Indie RPG development journal


#4 Bregma   Members   -  Reputation: 2766

Like
1Likes
Like

Posted 05 July 2012 - 11:02 AM

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

#5 sfx81   Members   -  Reputation: 131

Like
0Likes
Like

Posted 06 July 2012 - 02:15 AM

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.

#6 Codarki   Members   -  Reputation: 463

Like
1Likes
Like

Posted 06 July 2012 - 03:50 AM

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.

Edited by Codarki, 06 July 2012 - 03:51 AM.


#7 NightCreature83   Crossbones+   -  Reputation: 1158

Like
1Likes
Like

Posted 06 July 2012 - 07:03 AM

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.
Worked on titles: CMR:DiRT2, DiRT 3, DiRT: Showdown, GRID 2

#8 sfx81   Members   -  Reputation: 131

Like
0Likes
Like

Posted 06 July 2012 - 07:50 AM

Thanks all for responses. I think factory pattern is the way to go.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS