c++inheritanceoverridingvirtualusing

Using keyword with virtual inheritance in cpp


I want to resolve an inheritance problem of my Paladin class. Here is a resume of the inheritance between my classes :

class Peasant
{
    virtual int attack();
}

class Knight : virtual public Peasant
{
    int attack() override;
}

class Enchanter : public Peasant
{
    int attack() override;
}

class Priest : virtual public Enchanter

class Paladin : public Knight, public Priest
{
    using Knight::attack();
}

This way I got the following error :

Paladin.hpp:16:7: error: no unique final redefinition « virtual int Peasant::attack() » in « Paladin »
   16 | class Paladin : public Knight, public Priest
      |       ^~~~~~~

Words may differ in the official error message as I traduce this error from another language to english.

I solved my problem this way :

class Peasant
{
    int attack();
}

class Knight : virtual public Peasant
{
    int attack();
}

class Enchanter : public Peasant
{
    int attack();
}

class Priest : virtual public Enchanter

class Paladin : public Knight, public Priest
{
    using Knight::attack();
}

But I don't really like this solution. I prefer using virtual and override when I override the base's methods in derived classes. I know I could do :

class Peasant
{
    virtual int attack();
}

class Knight : virtual public Peasant
{
    virtual int attack() override;
}

class Enchanter : public Peasant
{
    virtual int attack() override;
}

class Priest : virtual public Enchanter

class Paladin : public Knight, public Priest
{
    int attack() override {return Knight::attack();};
}

But in the case I'm just re-using a method, I think it's more elegant to use using.

So I would like to know if there is a way to use both virtual/override and using in the same syntax.

Thank you in advance :D


Solution

  • Your second option is the correct way to go. using doesn't define a function, it brings a name into scope.

    You also have another error, attack is private in each of these classes, so you can't return Knight::attack().

    Not a syntax error, but you are missing virtual off your inheritance at least in Enchanter, and probably in Paladin.

    struct Peasant
    {
        virtual int attack();
    };
    
    struct Knight : virtual Peasant
    {
        int attack() override;
    };
    
    struct Enchanter : virtual Peasant
    {
        int attack() override;
    };
    
    struct Priest : virtual Enchanter
    {};
    
    struct Paladin : virtual Knight, virtual Priest
    {
        int attack() override { return Knight::attack(); };
    };
    

    However, trying to embed the rules of a game into subclasses within an inheritance hierarchy can be like fitting a round peg in a square hole.