Zamri Malakun
Zamri Malakun

Reputation: 267

Initializing references in the constructor

I am working on a game project, and my teammate has a certain way of solving our reference issues, and it works great, except, when the game is big, we will end up with massive constructors.

class Player
{
   private:
      Weapon *w1, *w2, *w3;
      Armor *a1, *a2;

  public:
      Player(Weapon *w1, Weapon *w2, ...) : w1(w1), w2(w2), ...;
}

Then my constructor is Player(w1, w2, w3, ...); which is disturbing, what if the player class had 100 references?

Is there a way to make this syntax simpler, or are we doing it wrong? Is there a better way of making references to variables which are outside the player class?

IMPORTANT The above is purely an example, a poorly written one. I don't just have weapons and armors. I have a ton of classes. I have a developer console reference, I have armor references, items, I have references to the debugging class, the logger class, and the list goes on. A vector is not helpful for me. Sorry for the poor example.

Upvotes: 0

Views: 174

Answers (3)

Some programmer dude
Some programmer dude

Reputation: 409482

You can indeed put it all in a single vector, if you use inheritance.

For a fantasy-themed game (which I assume you're writing) it could be something like this:

// The base object, contains common attributes
class Object { ... };

// The item class
class Item : public Object { ... };

class Weapon : public Item { ... };

class Sword : public Weapon { ... };

class Clothing : public Item { ... }

class Armour : public Clothing { ... };

Then it's enough with one vector for all equipment:

std::vector<std::shared_ptr<Item>> inventory;

For worn stuff, you could have separate variables, like

std::shared_ptr<Weapon> wielded;
std::shared_ptr<Clothing> head;  // Helmets, hats, etc.

Or use a map for the equipped stuff:

std::unordered_map<std::string, std::shared_ptr<Item>> equipped;

Then you can use e.g.

equipped["wielded"]

to get the wielded item.


For completeness, some other possible classes in the class tree above might be:

class Character : public Object { ... }

class Player : public Character { ... }

class Monster : public Character { ... }

class Dragon : public Monster { ... }

class RedDragon : public Dragon { ... }

class TheUltimateBossDragon : public RedDragon { ... }

As a side note, I have used hierarchies like the above in my own games previously. However in my next game (when and if I get that far) I will probably use another pattern, where classes indicates behavior. For example, a sword is equipable, it's a damage_inflicter, it's takeable, etc. This means more complex inheritance hierarchies, with much more multiple inheritance, and will probably use RTTI more. But on the bright side it will hopefully be more flexible.

Upvotes: 1

John Zwinck
John Zwinck

Reputation: 249642

Rather than having a fixed number of pointers to a small number of types, try using vectors:

class Player
{
   private:
      std::vector<Weapon*> weapons;
      std::vector<Armor*> armors;

  public:
      Player(const std::vector<Weapon*>&, const std::vector<Armor*>&);
}

Upvotes: 0

P0W
P0W

Reputation: 47854

Why not use vectors ?

std::vector<Weapon *> W;
std::vector<Armor *> A;

Upvotes: 1

Related Questions