Jump to content
  • Advertisement
Sign in to follow this  
hallgeir

Easiest way to copy from derived object to base object?

This topic is 4148 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi. As the topic says - what might be the easiest way to copy the data from one object to another, when the second object is derived from the first? Example:
class ClassA 
{
 ...
};
class ClassB : public ClassA 
{
 ...
};

int main(int, char **)
{
 ClassA ObjectA;
 ClassB ObjectB;

 //this obviously doesn't work, and I need a way around it:
 ClassB = ClassA

 return 0;
}
I could of course overload the = operator for EVERY derived class there is, but I'd think there is some better way. The reason I need to do this in the first place is because I'm storing all the objects that are loaded from files for my game in a std::vector<CGameObject*> array, and when I need to create a new object, I then need to copy the data from one of the objects in that array, to the new object. Example:
//assume there is a variable called ObjectData, which is of the type std::vector<CGameObject*>, 
//which contains all the data loaded from files. 
//All the objects on the actual map is stored in the array Objects, of the same type.

//let's say I want to create a Monster and add it to the world
void World::CreateObject(int objectid)
{
  CPlayer * player = new CPlayer;
  //this obviously doesn't work without an overloaded = operator since they are of different types.
  //*player = *ObjectData[objectid];
  Objects.push_back(player);
}
I hope someone understands my problem. So far I've overloaded the = operator for every derived class of CGameObject, but that isn't a great solution for me since the derived classes then need full access to all data members of the base class to be able to actually copy them. Any ideas on how I could solve this problem? All help is appreciated, thanks in advance. :) PS, a bit offtopic: If I may ask, how do I put the code in those nice little boxes with scrollbars on the forum? It'd be nice to know when posting larger amounts of code...

Share this post


Link to post
Share on other sites
Advertisement
I think the root of the problem is your initial design. It seems as though you are reading in all objects possible up front into some base class pointer and then when you need to actually create a specific object you no longer have the ability to get the data to set a derived object. Why not just let each object load up it's own attributes from the file. For the CPlayer class maybe the constructor is CPlayer(std::string filename) and it will read in all the data that a player type from the file. This is just one solution of many that I think would help solve your problem.

Then your CreateObject function might look like this:


void World::CreateObject(ObjectEnum objType)
{

// Either a switch statement on the enum, or an object factory
if (objType == PLAYER)
CBaseObject * object = new CPlayer("Player.txt");

Objects.push_back(object);

}




In this case I see no reason to overload the operator= from derived to base it does not seem like the right approach to the problem.

Also use the source tags for code snippets. The usage is in the faq section.

Share this post


Link to post
Share on other sites
Quote:
Original post by ziggwarth

//assume there is a variable called ObjectData, which is of the type std::vector<CGameObject*>,
//which contains all the data loaded from files.
//All the objects on the actual map is stored in the array Objects, of the same type.

//let's say I want to create a Monster and add it to the world
void World::CreateObject(int objectid)
{
CPlayer * player = new CPlayer;
//this obviously doesn't work without an overloaded = operator since they are of different types.
//*player = *ObjectData[objectid];
Objects.push_back(player);
}

You need to upcast.

void World::CreateObject(int objectid)
{
Objects.push_back(new CPlayer(dynamic_cast<CPlayer&>(*ObjectData[objectid]));
}

Of course, you will immediately lose any type information if your Objects collection is of type pointer-to-base-class. Oh, and be prepared to catch a std::bad_cast from the above if your objectid does not index a CPlayer. This will also create many copies of the same object, so make sure your object are cheap to construct and you're using a replacement for te new operator, since it's a pig. Um, and vtpiavoid vppusing adHungarian nsnnotation, prit vtpsmakes nscode avhard pnto vipsread.

Share this post


Link to post
Share on other sites
Thanks for the replies.

The reason I have done what I've done is that I could use only one piece of code to load the object data. But I will definitly look into letting each object load their own data, thank you. :)

I'm interested in any way I could improve my design... so any suggestions on how to do this is very welcome.

Share this post


Link to post
Share on other sites
I've solved it for now by moving the actual loading procedure to the object themselves. It seems to be working great so far. :)

Julian90: I've been thinking of implementing one of those object factories for some time, and I might just do it soon.

Thanks for the help guys.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!