abstract troubles

Started by
3 comments, last by Ezbez 16 years, 2 months ago
I am making a small game to test my skills. I have an Entity class, which is the base class for pretty much anything. It has a Create function which renders my 2d sprite at a given x, y. That is what is similar to each entity, but each entity is different and I need to pass data to it that defines what kind of the specific entity it is. Sounds confusing, so I'll try to show you what I mean: struct EnemyDefinition { int image_number; int health; float speed; char sprite_file[255]; //filename to use to make sprite }; My create function would be: Enemy.Create (int x, int y, EnemyDefinition *def) Now that is just one Entity (Enemy is derived from Entity). Let's say I have a Player entity. The Create function would be the same, except it would be Player.Create (int x, int y, PlayerDefinition *def). The third parameter is different in each Entity so I don't think I can use a pure virtual function, yet what I am trying to do it seems like I should be using one - since every single Entity has a Create function. Is there a smarter way to do this? [Edited by - Ryan Lepidi on February 4, 2008 8:09:40 AM]
Advertisement
could you just do


Enemy *myEnemy = EnemyDefition::Create(x,y);
Player *myPlayer = PlayerDefinition::Create(x,y);

so maybe EnemyDefintion, and PlayerDefinition should derive of type definition, which has a virtual method "create", and have enemy and player both derive of type "BaseObject" to give them a common return type. Then you can make a factory function that looks up the right def based on a string.

BaseObject *CreateObject(const std::string &objType, const int x, const int y){ if (objType.Compare("Enemy")  return EnemyDefinition::Create(x,y); else if (objType.Compare("Player")  return PlayerDefinition::Create(x,y);}
Quote:The Create function would be the same, except it would be Enemy::Create (int x, int y, PlayerDefinition *def).


Why would you call a function from Enemy to create a Player?

The functions that you have shown us appear to be static. That means that they cannot be virtual. It makes no sense, after all, to call a virtual static function and then expect it to somehow know which of the base classes you wanted it to call. What you are looking for is called "virtual constructors" and isn't directly supported in C++. But read that link.

You use a virtual function when you need to treat objects of differing types the same. Do you need to do this when you are creating them? Doesn't the creation of an object entail that you know its type and everything about it? Probably. Look into the Factory design pattern. The simplest way to do this is to create one function for each class. And use the function that you desire. Wait a minute... don't all classes come with such a function? Something that constructs them? Why yes - the constructor! (Subtle hint: use the constructor of the class that you are trying to instantiate.)


Entity* p = new Player(somedata);
Entity* e = new Enemy(other, data);

Edit: Oops, left out the news. Been using Python too long. :)
My mistake. I had :: instead of . because I just copied the function declaration into the forum post. I also didn't mean to create a player from an enemy. That was supposed to be player.
Alright, so what's the problem then? You have to provide constructors for all classes, and each constructor can take any type of arguments. They're not virtual, but virtual functions only make sense once you have an instance. I guess I don't see what's the issue.

Also, you should almost certainly use std::string instead of char[255].

This topic is closed to new replies.

Advertisement