Search code examples
c++classfunctionpolymorphismparent

Calling Non Virtual Method from child class


I know based on polymorphism that you cannot call a non virtual function/method

Ex:

class Entity
{
public: 
    Entity() { health = 10; }
    void DisplayHealth() { std::cout << health << std::endl; }
protected: 
    int health;
}; 

class Player : public Entity
{

};

class Enemy : public Entity
{
    void SetHealth(int n) { health = n; }
};

int main()
{
    Entity *instance = new Enemy(); 
    instance->SetHealth(1); // Error
    return 0;
}

so what I have come up with to counteract that is do something like this:

int main()
{
    Entity *instance = new Enemy(); 
    Enemy e = *(Enemy*)instance; 
    e.SetHealth(1); 
    instance = &e; 
}

This works fine for my needs but I'm wondering if this is the "correct" way of doing it. Is there a more efficient way to call a child class method using Polymorphism?


Solution

  • Entity *instance = new Enemy(); 
    Enemy e = *(Enemy*)instance;
    

    creates a new Enemy object and then assigns what is pointed to by instance to it. Which is redundant. and then

    instance = &e;
    

    causes memory leak because you just lost the pointer to new Enemy() and you have not deleted it.


    int main()
    {
        Entity *instance = new Enemy(); 
        Enemy *e = static_cast<Enemy*>(instance);  
              ^^ 
        e->SetHealth(1); 
    }
    

    ==================================================================================

    ==================================================================================

    However seeing as Health is a member of base class Entity, You can just move the setHealth function to Entity and be done with it.

    class Entity
    {
    public: 
        Entity() { health = 10; }
        void DisplayHealth() { std::cout << health << std::endl; }
        void SetHealth(int n) { health = n; }
    protected: 
        int health;
    };
    
    int main()
    {
        Entity *instance = new Enemy(); 
        instance->SetHealth(1); // Not Error Anymore
        return 0;
    }