一文详解C++子类函数为什么不能重载父类函数

 更新时间:2022年09月09日 11:26:48   作者:ithiker  
这篇文章主要介绍了一文详解C++子类函数为什么不能重载父类函数,文章围绕主题展开详细的内容戒杀,具有一定的参考价值,需要的朋友可以参考一下

先说结论:

子类成员函数的函数名和基类一样,但是函数声明与基类不一样的时候,不会和基类函数构成重载,而是会隐藏基类函数

简要回顾下C++中的基本概念:

  • 重写(override): 基类函数带virtual,子类函数声明和基类完全一样,实现不一样
  • 载(overload): 同一个类中,函数名一样,函数参数类型,个数,顺序等不一样的构成重载
  • 隐藏(hide): 子类函数名和基类一样,但是函数声明与基类不一样,就会对基类的函数进行隐藏

那么,子类函数名和基类一样,但是函数声明与基类不一样的时候,为什么不能重载基类函数呢?
先看

例子一

#include <stdio.h>

class Base {
public:
    virtual void foo(float a) {
        printf(" Base :: foo(float) \n");
    };

    virtual void foo(double a) {
        printf(" Base :: foo(double) \n");
    };
};

class Derived : public Base {
public:
    virtual void foo(double a) {
        printf(" Derived :: foo(double) \n");
    };

};

int main() {
    Derived d;
    float a = 3.0f;
    d.foo(a);

    Base b;
    b.foo(a);
}

如果重载可以发生在子类和基类之间,函数调用d.foo(a)的最佳匹配应该是Base::foo(float a),而实际输出是

Derived :: foo(double)

说明float类型的a向上转型为double,调用了子类的函数,重载没有在子类和基类间发生。这里如果类型转换不能发生,将不能通过编译。

而b.foo(a)的输出为:

Base :: foo(float) 

这说明重载在单个类内部进行。

如果实在想在子类中调用父类的函数,对于下面的例子二(不能编译通过):

class A
{
public:
  void a() {}
};

class B : public A
{
public:
  void a(int) {}
};

int main()
{
  B b;
  b.a();
}

如果需要上面的函数可以编译通过,我们可以这样做:

  • 在class B 内部加上using A::a
  • 调用时使用b.A::a(),不推荐这样做

当然,问题的关键是为什么C++的设计者这么设计,从技术实现来说,访问基类函数来进行名字查找,实现跨类重载没有太大的难度。但是从实际用户意图来说,像上面B中添加void a(int)函数的目的就是为了重新实现A的接口,并隐藏原来的接口;当然,如果用户不想隐藏,可以加上using A::a。
另外,对于例子一,如果实现了跨类重载,那么d.foo(a)将也会调用到基类的函数,尽管float可以转型到float, 将很容易引起混淆

顺应用户意图和避免不必要的混淆,这可能就是C++设计者这么设计的原因。

到此这篇关于一文详解C++子类函数为什么不能重载父类函数的文章就介绍到这了,更多相关C++子类函数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解c++优先队列priority_queue的用法

    详解c++优先队列priority_queue的用法

    本文详细讲解了c++优先队列priority_queue的用法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • Clion配置C语言环境的步骤详解

    Clion配置C语言环境的步骤详解

    这篇文章主要介绍了Clion配置C语言环境的步骤详解,本文分步骤通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-02-02
  • Qt实现UI界面纯代码示例

    Qt实现UI界面纯代码示例

    这篇文章主要给大家介绍了关于Qt实现UI界面的相关资料,使用Qt纯代码,实现了基本的界面,对大家学习或者使用Qt具有一定的参考借鉴价值,需要的朋友可以参考下
    2024-01-01
  • c++ class中成员与分配内存的问题详解

    c++ class中成员与分配内存的问题详解

    很多人都知道C++类是由结构体发展得来的,所以他们的成员变量(C语言的结构体只有成员变量)的内存分配机制是一样的,下面这篇文章主要给大家介绍了关于c++ class中成员与分配内存问题的相关资料,需要的朋友可以参考下
    2021-10-10
  • C++之const限定符详解

    C++之const限定符详解

    这篇文章主要为大家介绍了C++之const限定符,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2021-12-12
  • C 二分查找 递归与非递归的实现代码

    C 二分查找 递归与非递归的实现代码

    C 二分查找 递归与非递归的实现代码,需要的朋友可以参考一下
    2013-03-03
  • Clion配置opencv开发环境的详细过程

    Clion配置opencv开发环境的详细过程

    这篇文章主要介绍了Clion配置opencv开发环境的详细过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考的下
    2022-04-04
  • 解析Linux下的时间函数:设置以及获取时间的方法

    解析Linux下的时间函数:设置以及获取时间的方法

    本篇文章是对Linux下的时间函数:设置以及获取时间的方法进行了详细的分析介绍,需要的朋友参考下
    2013-05-05
  • C语言JNI的动态注册详解

    C语言JNI的动态注册详解

    这篇文章主要介绍了JAVA JNI的动态注册,这里提供简单实例代码,需要的朋友可以参考下,小编觉得写的还不错,希望能给你带来帮助
    2021-08-08
  • C++中constexpr与模板元编程的基础、常见问题、易错点及其规避策略

    C++中constexpr与模板元编程的基础、常见问题、易错点及其规避策略

    C++编译时计算允许程序在编译阶段完成计算任务,constexpr与模板元编程是C编译时计算的两把利剑,它们不仅能够提升程序的性能,还能增强代码的健壮性和可维护性,通过避开本文阐述的易错点,开发者可以更加得心应手地运用这些特性,编写出既高效又优雅的C代码
    2024-06-06

最新评论