2

I have a base class Character, that can Attack(), and derived classes Magician(10), Elf(5) or Giant(15). Magicians can evolve to BlackMagician(15)

each type of Character has a defined Power(in parenthesis). My question is how to associate a class with a static function getFamilyPower() and overrride it, accordingly.

The code is below: https://codecollab.io/@sdudnic/warriors

The idea is the following:

class Character {
    static int power;
public:
    static int getPower() { return power; }
    virtual int Attack(Character *other) { /*...*/ }
};

class Magician : public Character {
    static int power = 10;
public:
    static int getPower() {return power; }
};

class Elf : public Character {
    static int power = 5;
public:
    static int getPower() {return power; }
};

class Giant : public Character {
    static int power = 15;
public:
    static int getPower() {return power; }
};
serge
  • 13,940
  • 35
  • 121
  • 205
  • 3
    Please show the code, instead of just describing it. – cigien Nov 03 '20 at 18:32
  • 1
    I don't know if I got that right, but it sounds to me like you either want Character.Attack() to be virtual or have a member Character::power that gets set by your derived classes and used by Character.Attack(). – Stefan Riedel Nov 03 '20 at 18:39
  • 1
    You can only override a virtual function, so no static. – n. m. could be an AI Nov 03 '20 at 18:41
  • 1
    How should a static function with no parameters know which instance is used? – Surt Nov 03 '20 at 19:02
  • 1
    @Surt he's talking about overriding, not overloading – Stefan Riedel Nov 03 '20 at 21:27
  • my idea is to have a static member `power` in each class, and return that power in `getPower()` static function – serge Nov 04 '20 at 11:23
  • @cigien I added the code please review my question – serge Nov 04 '20 at 11:37
  • Thanks, that's much better :) I'm voting to reopen. – cigien Nov 04 '20 at 11:42
  • 1
    @Serge why are you so keen on using `static`? I don't think you understand what `static` really does. It is not going to work in your situation, especially when you take evolution into account. – Remy Lebeau Nov 04 '20 at 15:33
  • @RemyLebeau, is somthing similar to this question https://stackoverflow.com/questions/53962095/static-variable-for-each-extended-class where each class has its own "number" – serge Nov 05 '20 at 22:53
  • @Serge that is a completely different situation, and that solution doesn't apply to your situation. Even if you ignore your requirement to support per-character evolutions (which prevents you from using a `static` number for evolved entities), you would still need a non-static virtual method in order to return the per-character numbers in a polymorphic manner correctly. – Remy Lebeau Nov 05 '20 at 23:26

2 Answers2

2

Only virtual methods can be overridden. But a static method cannot be virtual, as it has no this instance pointer from which to access a vtable. So each Character will need a non-static virtual method to report its current power level, eg:

class Character
{
public:
    int health = 100;

    void Attack(Character *other) {
        int myPower = Power();
        int theirPower = other->Power();
        if (theirPower > myPower)
            health -= theirPower;
        else if (theirPower < myPower)
            other->health -= myPower;
    }

    virtual int Power() = 0;
    virtual void Evolve() {}
};

class Magician : public Character
{
public:
    bool isBlack = false;

    int Power() override { return isBlack ? 15 : 10; }

    void Evolve() override { isBlack = true; }
};

class Elf : public Character
{
public:
    int Power() override { return 5; }
};

class Giant : public Character
{
public:
    int Power() override { return 15; }
};
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
-1

I think you may be confusing static for const.

private: const int power = 10; // in base class for a default value of 10

//virtualize and override the Power function to the return the const int value.