Storing class pointers vector (RPG Code Structure-wise)

209 views Asked by At

I am building small components that will be used for a RPG later on, however my experience in this scale of project is very limited, which is why I choose to build them independant of each other. This part will cover character creation and handling.

So I have the following vector that stores class pointers of Gender. I know there will only be four genders, Unknown (for error-catching), Male, Female and Neuter.

std::vector<Gender*> mGenders;

However for some other vectors I do not know the exact amount.

std::vector<BClass*> mBClasses;

I have Creatures that have a mGenderID as well as a mBClassID. I have a game.h that initializes all genders and base classes (among many others). Let's say I have a

Creature* mPC = new Creature ("Name", GenderID, BClassID);

Should I then have a

Gender* Game::getGenderByID(int id) {
    for (std::vector<Gender*>::iterator it = mGenders.begin(); it != mGenders.end(); ++i) {
        if ((*it)->getID() == id) return (*it)
    }
}

And use it the following way

std::cout << "Your name is " << mPC->getName() << ". Your gender is " << getCreatureByID(mPC->getGenderID())->getName();

So my question is, is this a good way of structuring the code? Imagine an infinite-engine like game, Baldur's Gate or so. Preferebly it should work for most, even if I were to do a Skyrim or GTA-like game.

Lastly, how easy would this be to port for C#? As I know C++ better than C#, I thought I'd give it a go in C++ first, to get the structure correct and work with something that can be used in larger-scale projects.

Edit: Would it be better to directly store the Gender* in the Creature class? And no the ID of the creature?

Edit2:

class Gender {
public:
Gender::Gender(int id, std::string name, std::string desc, int coeBonus, int strBonus, int agiBonus, int attBonus, int intBonus, int chaBonus);
~Gender();

int getID () const;
std::string getName () const;
std::string getDesc () const;

int getStrBonus () const;
int getAgiBonus () const;
int getAttBonus () const;
int getIntBonus () const;
int getChaBonus () const;
int getCoeBonus () const;

private:
int mID;
std::string mName;
std::string mDesc;
int mStrBonus;
int mAgiBonus;
int mAttBonus;
int mIntBonus;
int mChaBonus;
int mCoeBonus;
};

The definition of gender.h

Thanks in advance

2

There are 2 answers

1
Joseph Mansfield On
std::vector<Gender*> mGenders;

I can't see a good reason to be storing pointers in your vector. Why not just have a std::vector<Gender>?

Anyway, it seems like a strange idea to have a container of Genders. As you say, you have 4 possible genders, which you are then storing in this vector. So the vector is always size 4 and you never remove anything from it or add anything to it? And each element basically just represents a possible gender that a creature can have? That is, you're enumerating the possible genders. Sounds like you want an enum (or enum class) instead!

enum class gender {
  unknown,
  male,
  female,
  neuter
};

Then there's no need to mess around with ugly IDs that don't really mean anything (at least, they're hidden behind the enum now).

Then you could create a creature like so:

Creature mPC("Name", gender::male);

If you then want to print these out, you'll need some kind of mapping from enum value to strings. One way to do this is to just have a function that switches on the gender argument and returns an appropriate string. Alternatively, you can create a std::map like so:

std::map<gender, std::string> genderNames =
    {{gender::unknown, "Unknown"}, /* ... */};

Then you can print a particular creatures gender just by doing:

std::cout << genderNames[mPC.getGender()];

You seem to have an unhealthy tendency to want to use dynamic allocation for your objects. Don't do it unless it's necessary, and when it is necessary, prefer smart pointers over raw pointers.

0
Emz On

With much help from gamedev I am now happy with how much code is structed.

Instead of storing integers containing the IDs of genders, races, and so forth. I now store a pointer to them. Rendering the getGenderByID(int id) obsolete atm.

I am also currently working on a buff/debuff (effect) system instead of having all the different bonus variables.

These changes should make the code good enough for practice!

Gender::Gender(int id, std::string name, std::string desc, int coeBonus, int strBonus, int agiBonus, int attBonus, int intBonus, int chaBonus);

to

Gender(int id, std::string name, std::string desc, Effect* effect);

Currently working on the Effect class, so can't tell a lot about it.

Thanks for the comments.