Home > Software design >  Overriding method shadows overloaded final version
Overriding method shadows overloaded final version

Time:12-20

I have the following code:

struct Abs {
    virtual void f(int x) = 0;
    virtual void f(double x) final { std::cout << 2; }
};

struct Sub: public Abs {
    void f(int x) final { std::cout << 1; }
};

Abs is an abstract class which comprises a pure member function void f(int) and its overloaded version void f(double x), which is no longer pure and final. If I try to override void f(int) in the derived struct Sub, it shadows void f(double) and the following main function prints 1, converting 1.01 to int:

int main() {
    Sub x = {};
    x.f(1.01);
    return 0;
}

How do I overcome this problem? Also, why does it work like that?

CodePudding user response:

Given x.f(1.01);, the name f is found in the scope of class Sub, then name lookup stops; the scope of Abs won't be examined. Only Sub::f would be put in overload set and then overload resolution is performed.

... name lookup examines the scopes as described below, until it finds at least one declaration of any kind, at which time the lookup stops and no further scopes are examined.

You can use using to introduce the names of Abs into Sub, then Abs::f could be found and take part in overload resolution too.

struct Sub: public Abs {
    using Abs::f;
    void f(int x) final { std::cout << 1; }
};

CodePudding user response:

You have to add the using clause into your derived class to pick all the overloads from the base class.

struct Abs {
    virtual void f(int x) = 0;
    virtual void f(double x) final {std::cout << 2;} 
};

struct Sub: public Abs {
    using Abs::f;   // << this one did the trick
    void f(int x) final { std::cout << 1; }
};

int main() {
    Sub x = {}; 
    x.f(1.01);
    return 0;
}
  • Related