重写方法会影响重载的最终版本

Overriding method shadows overloaded final version

我有以下代码:

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是一个抽象class,它包含一个纯成员函数void f(int)和它的重载版本void f(double x),不再是纯成员函数final .如果我尝试在派生结构 Sub 中覆盖 void f(int),它会隐藏 void f(double) 并且下面的 main 函数打印 1,将 1.01 转换为int:

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

如何克服这个问题?另外,为什么会这样?

给定x.f(1.01);,名字f在classSub的范围内找到,那么name lookup停止; Abs 的范围不会被检查。只有Sub::f被放入重载集中,然后进行重载解析。

... 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.

可以用usingAbs的名字引入Sub,这样就可以找到Abs::f,也参与重载决议[=23] =]

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

您必须将 using 子句添加到您的派生 class 中以从基础 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;
}