Home > Back-end >  Use child variable without to rewrite function Class
Use child variable without to rewrite function Class

Time:01-25

I have a question is possible to use children variable for display something.

For example:

// Entity.hpp

class Entity {
    public:
        Entity();
        ~Entity();
        // For this function
        virtual void attack();
        virtual int getNbAttack();

    protected:
    private:
        int _nbAttack = 0;
        int _nbAttackCost = 0;
        std::string _msgAttack = "message class Entity";
};
// Player.hpp

class Player : public {
    public:
        Entity();
        ~Entity();

    protected:
    private:
        int _nbAttack = 5;
        int _nbAttackCost = 5;
        std::string _msgAttack = "message class Player";
};
// Entity.cpp


int Entity::attack() {
    this->_power -= 10;
    std::cout << _msgAttack << std::endl;
    return this->_nbAttack;
}

Is it possible to do so:

// Main.cpp
Entity entity;
entity.attack();
std::cout << entity.getNbAttack() << std::endl;

Player player;
player.attack();
std::cout << player.getNbAttack() << std::endl;

Result:

message class Entity
0

message class Player
5

Is this possible or do I have to rewrite my function?

Thanks in advance for your help!

CodePudding user response:

You can absolutely do that. But you need to make a few changes to the code you posted:

  • add Entity as base class to the class definition of Player (it is missing after public)
  • make the data members of Entity protected or add protected setters for them
  • if you want to use the base class' constructors in your derived class, use using Entity::Entity;, but declare Player's constructors/destructor with Player(); and ~Player(); respectively.
  • there is a member variable declaration missing (power)
  • [optional] you can get rid of the this-> to access members from inside the class. You can use it, but it is not strictly necessary

Generally I've got two tips:

First: Just try it out. Use the compiler and run your program. You can also use pages like https://godbolt.org/ to run your code (beware it might be too much information for a beginner).

Second: Get a good book on the programming language and/or see https://en.cppreference.com/w/cpp

CodePudding user response:

You could do this, but at least in my opinion, it's a fairly poor idea.

If you want two classes that are otherwise similar, but store different fixed values I'd use a template:

#include <iostream>

// This is to represent a string literal, since we can't actually
// pass a string literal as a template argument.
template<size_t N>
struct string_literal {
    char data[N];

    constexpr string_literal(const char (&input)[N]) {
        std::copy_n(input, N, data);
    }

    operator char const *() const { return data; }
};

template <int N, string_literal name>
class basic_entity {
public:
    int attack() const {
        std::cout << name << " attack ";
        return nbAttack;
    }
private:
    int nbAttack = N;
};

int main() {
    using Entity = basic_entity<0, "Entity">;
    using Player = basic_entity<5, "PLayer">;

    Entity entity;
    Player player;

    std::cout << entity.attack() << "\n";
    std::cout << player.attack() << "\n"; 
}

This produces a result like this:

Entity attack 0
PLayer attack 5

I can see two cases where it would be worth considering inheritance. The first would be that you're using an older compiler (the string_literal class requires C 20). The second would be if you want to be able to create a single container of items where each item could be either an Entity or a Player (or more accurately, a pointer to one of them). That could also be implemented using an std::variant<Entity, Player>, however, and this might be the preferred alternative (in particular, each item would still be allocated "in place" instead of requiring container of pointers to individually allocated items).

  •  Tags:  
  • Related