wstyczen
wstyczen

Reputation: 17

How can I declare an instance of any inherited class?

I started writting a simple program with classes in C++ to get comfortable with OOP. I wrote a class Game that takes instances of classes Player and Unit as attributes:

#ifndef GAME_HPP
#define GAME_HPP

#include "Unit.hpp"
#include "Player.hpp"

class Game
{
public:
    //ATTRIBUTES
    Player player;
    Unit mob;
    
    //CONSTRUCTORS
    Game(Player, Unit){};
    
    //METHODS
    std::string get_n_chars(char, int);
    void print_player_character_panel();
    void print_enemy_character_panel();
    void print_character_panels();

};

#endif // GAME_HPP

I want the 'mob' attribute to take any inherited class of 'Unit', i.e.

class Goblin : public Unit
{...
int main()
{    
    Player hero{"Boi"};
    Goblin goblin;

    Game game1(hero, goblin);
    
    return 0;
}

But when I do this then 'mob' only has the attributes and methods of a 'Unit'. Like this:

https://i.sstatic.net/nShv3.png

And even attributes from the contructor changed:

https://i.sstatic.net/mPrW2.png

Can I somehow declare an instance of any inherited class of 'Unit' as mob attribute and for it to remain an instance of that class instead of 'Unit.'

Upvotes: 2

Views: 211

Answers (1)

einpoklum
einpoklum

Reputation: 131666

tl;dr: Consider using a variant.

Can I somehow declare an instance of any inherited class of 'Unit' as mob attribute and for it to remain an instance of that class instead of 'Unit.'

As long as you are willing to state, at compile time, which classes inherit Unit, then - yes, sort of. You can use a std::variant - which is a fancier of form of a union.

Supposing your unit types are Goblin, Troll and Wizard, this would be: std::variant<Goblin, Troll, Wizard>.

Note, however, that a variant class is not the same as the base class that is common to all of the variant types. In other words, std::variant<Goblin, Troll, Wizard> may be a unit in our minds, but it is not a Unit as far as the C++ compiler is concerned. So you will have to do a bit of work to run code which takes Unit& or Unit*, or methods of Unit.

Here's a tutorial on using std::variant, which I recommend if you haven't worked with it before:

Simplify C++: Modern C++ Features – std::variant and std::visit

Upvotes: 1

Related Questions