0

I have two classes that intend to function the same but with different data members, as such:

class Character
{
protected:
    string job;
    int MAX_HP;
    int HP;
    int STR;
    int DEX;
    int INT;

public:
    Character();
    Character(string job,
              int max_hp,
              int str=0, int dex=0, int inte=0);
    string get_name();
    // get func and set func
    int get_MAX_HP();
    void add_MAX_HP(int MAX_HP);
    int get_HP();
    void add_HP(int HP);
    int get_STR();
    void add_STR(int STR);
    int get_DEX();
    void add_DEX(int DEX);
    int get_INT();
    void add_INT(int INT);
}
class Monster
{
protected:
    string name;
    int MAX_HP;
    int HP;
    int ATK;
    int DEF;

public:
    Monster(string name, int MAX_HP, int Shield, int Barrier, int ATK, int DEF);
    string get_name();
    int get_MAX_HP();
    void add_MAX_HP(int MAX_HP);
    int get_HP();
    void add_HP(int HP);
    int get_ATK();
    void add_ATK(int ATK);
    int get_DEF();
    void add_DEF(int DEF);
}

These are all the difference between the two classes I have designed so far. As I am writing the other functionalities I start to realize that they work essentially the same despite the different data members, along with their getter and setter. I feel like making the two class declarations code into one. I think I can write a virtual base class for sure, that contains the union of all data members and member functions, and only initialize some members for Character or Monster. But can I achieve it with template? With template Character and Monster are instantiation of one template, but I am uncertain whether can template initialize different members in response to different typename...

Edit: Allow me to be more specific. The Character and Monster are designed to fight. It also allows the Character and Character, Monster and Monster to fight. With two classes, there will be four member function in total to design:

class Character{
    void Fight(Character hero, Monster enemy);
    void Fight(Character hero, Character enemy);
}

class Monster{
    void Fight(Monster mon, Character enemy);
    void Fight(Monster mon, Monster enemy);
}

I want to make the Fight() function spread among two classes into one block to save code, as they all share using ATK/STR/DEX/INT to deduct HP of other object, DEF deducted for Monster. In finishing writing the function, I suspect a lot of copy & paste would be done, and code is already lengthy for getter and setter with similar functionalities, for each data member. I noticed a partial specialization for template. But it would be the same to write two separate code blocks for Character and Monster. Is it my class design that impedes merging homogeneous codes, or is it inevitable for C++, to write class with slight difference?

Jack Lee
  • 73
  • 5
  • What exactly do you expect the template to be a template ***of***, in concrete terms? – Sam Varshavchik Jul 23 '22 at 14:07
  • Are you thinking of curiously recurring template pattern? https://stackoverflow.com/questions/4173254/what-is-the-curiously-recurring-template-pattern-crtp Also, virtual base class probably doesn't mean what you think it means. Otherwise, why do you think one is necessary? https://stackoverflow.com/questions/21558/in-c-what-is-a-virtual-base-class – Homer512 Jul 23 '22 at 14:13
  • 3
    The base class shouldn't contain the union of all member functions - it should contain the intersection, the behaviors that `Character` and `Monster` have in common, and that the calling code can work with without having to know which of the two it's actually manipulating. – Igor Tandetnik Jul 23 '22 at 14:18
  • The proposal to create the universal class (with a rational union of all members) will be the simplest. Creating a virtual base-class as the union rather than intersection will just add complexity. In my experience virtual base classes cause at least as many problems as they solve. The common pattern here is the Strategy Pattern. Have a single class that holds the data (name and attributes) and slot-in classes for behaviours. – Persixty Jul 23 '22 at 14:20
  • Out of context many solutions might be fine... If you want a collection that contains both characters and monster and them mostly the same, then a base class with virtual methods might be appropriate... – Phil1970 Jul 23 '22 at 14:26
  • I think you forgot to give the player a name. – apple apple Jul 23 '22 at 14:32

0 Answers0