代码之家  ›  专栏  ›  技术社区  ›  Milo

用非纯虚拟版本[duplicate]重载纯虚拟函数

c++
  •  10
  • Milo  · 技术社区  · 6 年前

    基和派生的定义如下:

    class Base {
    
        public:
            virtual int f1(int a) const = 0;
            virtual int f2(int a, int b) const { return a+b;}
    };
    
    class Derived : public Base {
    
        public:
            int f1(int a) const { return a; }
    }; 
    
    int main() {
        Derived obj;
        cout << obj.f1(1) << endl;
        cout << obj.f2(1, 2) << endl;
    }
    

    结果是

    1
    3
    

    目标f1(1) 使用 f1层 实施自 派生 目标f2(1,2) 使用继承自的实现 底座 ,这就是我想要的。

    现在,我希望这两个函数的名称相同, f ,因此基类提供了一个实现,当有两个参数时,派生类必须实现单参数版本(这就是为什么它是纯虚拟的)。

    但是,如果我这样做(只需重命名 f1层 f2层 ):

    class Base {
    
        public:
            virtual int f(int a) const = 0;
            virtual int f(int a, int b) const { return a + b;}
    };
    
    class Derived : public Base {
    
        public:
            int f(int a) const { return a; }
    };
    
    int main() {
        Derived obj;
        cout << obj.f(1) << endl;
        cout << obj.f(1, 2) << endl;
    }
    

    我得到以下错误:

    20:23: error: no matching function for call to 'Derived::f(int, int)'
    20:23: note: candidate is:
    14:13: note: virtual int Derived::f(int) const
    14:13: note:   candidate expects 1 argument, 2 provided
    

    为什么会这样?这种超载不可能吗?

    5 回复  |  直到 6 年前
        1
  •  10
  •   Bathsheba    6 年前

    你需要写信

    class Derived : public Base {
    
        public:
            using Base::f;
            int f(int a) const { return a; }
    };
    

    注意 using 声明。这将基类版本带回范围。

        2
  •  8
  •   Geezer    6 年前

    f

    你需要写信

    class Derived : public Base {
    
        public:
            using Base::f;
            int f(int a) const { return a; }
    };
    

    using 声明。这将基类版本带回范围。[感谢@Bathsheba]

    为什么会这样?这种超载不可能吗?

    [basic.scope.hiding¶3] :

    在成员函数定义中,在块中对名称的声明 作用域隐藏具有相同 名称;参见[基本范围类]. 成员在会议上的声明 看到了吗[class.member.lookup].

    姓名 ,而不是重载。因此,基类中是否有其他重载并不重要, 他们都有一个共同点 名称 ,根据上面的引文隐藏。

        3
  •  1
  •   user32434999    6 年前

    using Base::f; 或者你也可以为f的某些版本写一些这样的东西: int f(int a, int b) const override {return Base::f(a,b);}

    class Derived : public Base {
    
    public:
        int f(int a) const { return a; }
        int f(int a, int b) const override {return Base::f(a,b);} 
    };
    

    使用的版本已在本文中提到 answer :

    class Derived : public Base {
    
        public:
            using Base::f;
            int f(int a) const { return a; }
    };
    

    注:

        4
  •  0
  •   dan    6 年前

    f 可以显式调用 f 基类的

    int main() {
        Derived obj;
        cout << obj.f1(1) << endl;
        cout << obj.Base::f2(1, 2) << endl;
    }
    
        5
  •  -2
  •   Ibrahima Keita    6 年前