【C++ 概念区分】C++ 中覆盖,重写,隐藏 三者的区别

简介: 【C++ 概念区分】C++ 中覆盖,重写,隐藏 三者的区别
角度/特性 覆盖(Overriding) 重载(Overloading) 隐藏(Hiding)
定义 子类中的函数与父类中的函数具有相同的函数名和参数列表,但可能有不同的实现。 同一个类中的函数具有相同的函数名,但参数列表不同。 子类中的函数与父类中的函数具有相同的函数名,但参数列表可能不同。
作用 改变父类中的函数的行为。 提供多种方式来执行相同的任务。 阻止父类中的函数在子类中的访问。
调用 通过父类的引用或指针调用子类对象时,会调用子类的函数。 根据传递的参数类型和数量,编译器决定调用哪个函数。 通过子类的引用或指针调用时,只能访问子类的函数。
多态性 支持多态性。 不支持多态性。 不支持多态性。
使用场景 当子类需要改变父类的行为时使用。 当需要执行相同的任务,但输入参数类型或数量不同时使用。 当子类需要阻止父类函数的访问时使用。

重载overload

在C++编程中,重载(overload)是一种强大的功能,它允许在同一可访问区内声明几个具有不同参数列表的同名函数。程序会根据不同的参数列表来确定具体调用哪个函数,这种机制就是重载。

重载的特征包括:

  1. 函数必须处在相同的空间中,即相同的范围内。
  2. 函数名必须相同。
  3. 参数必须不同,即参数个数不同,或相同位置的参数类型不同。
  4. const成员函数可以和非const成员函数形成重载。
  5. virtual关键字、返回类型对是否构成重载无任何影响。

需要注意的是,重载不关心函数的返回值类型,即返回类型不同无法构成重载。这是因为在调用函数时,编译器并不知道函数返回值将被如何使用,因此无法根据返回类型来选择合适的重载版本。

此外,C++中的const成员函数也可以构成overload。这是因为const成员函数和非const成员函数在对象的const性上有所不同,因此它们可以被视为两个不同的函数。

总的来说,重载是C++中的一种重要特性,它提供了代码的灵活性和可读性,使得函数可以根据不同的参数类型和数量进行不同的操作。

覆盖override

覆盖(Override)是面向对象编程中的一个重要概念。它指的是在派生类(子类)中重新定义父类中的函数。覆盖的函数,其函数名、参数列表、返回值类型必须与父类中被覆盖的函数完全一致。覆盖函数和被覆盖函数的主要区别在于函数体,也就是花括号中的部分。当派生类对象调用这个同名函数时,系统会自动调用派生类中的覆盖版本,而不是父类中的被覆盖函数版本,这种机制就被称为覆盖。

覆盖的特征包括:

  1. 不同的范围:覆盖函数位于派生类,被覆盖函数位于基类。
  2. 函数名字相同:覆盖函数和被覆盖函数的名称必须完全一致。
  3. 参数相同:覆盖函数和被覆盖函数的参数列表必须完全一致。
  4. 基类函数必须有virtual关键字:只有被声明为virtual的基类函数才能被派生类覆盖。

覆盖的主要目的是为了让派生类可以改变和扩展基类的行为。通过覆盖,派生类可以提供与基类函数相同的接口,但具有不同的实现,这样可以增加代码的灵活性和可重用性。同时,覆盖也是多态性的一个重要体现,使得我们可以通过基类的指针或引用来调用派生类的函数,从而实现动态绑定。

隐藏hide

所谓的"隐藏",在面向对象编程中,特指当派生类类型的对象、指针、引用访问基类和派生类都有的同名函数时,访问的是派生类的函数,这就相当于隐藏了基类的同名函数。这种隐藏规则的底层原因其实是C++的名字解析过程。在继承机制下,派生类的类域被嵌套在基类的类域中。派生类的名字解析过程如下:

  1. 首先在派生类类域中查找该名字。
  2. 如果第一步中没有成功查找到该名字,即在派生类的类域中无法对该名字进行解析,则编译器在外围基类类域对查找该名字的定义。

隐藏的特征主要有两个:

  1. 如果派生类的函数与基类的函数同名,但是参数不同。此时,不论有无virtual关键字,基类的函数将被隐藏。这是因为在C++中,函数的参数列表是函数签名的一部分,如果参数列表不同,那么这两个函数就被视为完全不同的函数。这种情况下,派生类的函数并不是重载基类的函数,而是隐藏了基类的函数。
  2. 如果派生类的函数与基类的函数同名,并且参数也相同,但是基类函数没有virtual关键字。此时,基类的函数被隐藏。这是因为在C++中,只有当基类的函数被声明为virtual时,派生类的同名函数才会覆盖基类的函数,否则,派生类的函数会隐藏基类的函数。

总的来说,函数的隐藏是C++中一个重要的概念,理解这个概念对于理解C++的继承和多态机制有着重要的作用。

编译器的处理过程

在C++中,覆盖(Overriding)、重载(Overloading)和隐藏(Hiding)是三种不同的概念,它们在编译器处理上有着不同的机制。

  1. 覆盖(Overriding):覆盖发生在继承关系中,当派生类中的函数和基类中的虚函数有相同的函数名和参数列表时,我们说派生类的函数覆盖了基类的函数。在编译器处理覆盖时,会在虚函数表(vtable)中为派生类的函数分配一个新的入口,这样在运行时,通过基类指针或引用调用该函数时,会根据虚函数表找到派生类的函数,实现动态绑定。
  2. 重载(Overloading):重载是指在同一作用域中,有多个同名函数,但参数列表不同。编译器处理重载时,会根据函数调用时提供的参数类型和数量,选择最匹配的函数进行调用。这个过程在编译时完成,称为静态绑定。
  3. 隐藏(Hiding):隐藏发生在继承关系中,当派生类中的函数和基类中的函数有相同的函数名,但参数列表不同,或者函数名和参数列表相同但基类函数不是虚函数时,我们说派生类的函数隐藏了基类的函数。在编译器处理隐藏时,会优先在派生类的作用域中查找函数,如果找到了就调用派生类的函数,否则就在基类的作用域中查找。这个过程也是在编译时完成,称为静态绑定。

总的来说,覆盖涉及到运行时的动态绑定,而重载和隐藏涉及到编译时的静态绑定。这三种机制都是C++中多态性的重要组成部分。

结语

在我们的编程学习之旅中,理解是我们迈向更高层次的重要一步。然而,掌握新技能、新理念,始终需要时间和坚持。从心理学的角度看,学习往往伴随着不断的试错和调整,这就像是我们的大脑在逐渐优化其解决问题的“算法”。

这就是为什么当我们遇到错误,我们应该将其视为学习和进步的机会,而不仅仅是困扰。通过理解和解决这些问题,我们不仅可以修复当前的代码,更可以提升我们的编程能力,防止在未来的项目中犯相同的错误。

我鼓励大家积极参与进来,不断提升自己的编程技术。无论你是初学者还是有经验的开发者,我希望我的博客能对你的学习之路有所帮助。如果你觉得这篇文章有用,不妨点击收藏,或者留下你的评论分享你的见解和经验,也欢迎你对我博客的内容提出建议和问题。每一次的点赞、评论、分享和关注都是对我的最大支持,也是对我持续分享和创作的动力。

目录
打赏
0
0
0
0
216
分享
相关文章
【c++】多态(多态的概念及实现、虚函数重写、纯虚函数和抽象类、虚函数表、多态的实现过程)
本文介绍了面向对象编程中的多态特性,涵盖其概念、实现条件及原理。多态指“一个接口,多种实现”,通过基类指针或引用来调用不同派生类的重写虚函数,实现运行时多态。文中详细解释了虚函数、虚函数表(vtable)、纯虚函数与抽象类的概念,并通过代码示例展示了多态的具体应用。此外,还讨论了动态绑定和静态绑定的区别,帮助读者深入理解多态机制。最后总结了多态在编程中的重要性和应用场景。 文章结构清晰,从基础到深入,适合初学者和有一定基础的开发者学习。如果你觉得内容有帮助,请点赞支持。 ❤❤❤
104 0
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
C 语言的关键字 static 和 C++ 的关键字 static 有什么区别
在C语言中,`static`关键字主要用于变量声明,使得该变量的作用域被限制在其被声明的函数内部,且在整个程序运行期间保留其值。而在C++中,除了继承了C的特性外,`static`还可以用于类成员,使该成员被所有类实例共享,同时在类外进行初始化。这使得C++中的`static`具有更广泛的应用场景,不仅限于控制变量的作用域和生存期。
135 10
|
5月前
|
实现两个变量值的互换[C语言和C++的区别]
实现两个变量值的互换[C语言和C++的区别]
68 0
C++入门教程:掌握函数重载、引用与内联函数的概念
通过上述介绍和实例,我们可以看到,函数重载提供了多态性;引用提高了函数调用的效率和便捷性;内联函数则在保证代码清晰的同时,提高了程序的运行效率。掌握这些概念,对于初学者来说是非常重要的,它们是提升C++编程技能的基石。
48 0
C++内存管理(区别C语言)深度对比
C++内存管理(区别C语言)深度对比
114 5
Rust与C++的区别及使用问题之对于大量使用C++实现的产品来说,迁移到Rust的问题如何解决
Rust与C++的区别及使用问题之对于大量使用C++实现的产品来说,迁移到Rust的问题如何解决
Inno setup 脚本判断 Microsoft Visual C++ Redistributable 不同版本区别
Inno setup 脚本判断 Microsoft Visual C++ Redistributable 不同版本区别
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
【C++进阶】特殊类设计 && 单例模式
通过对特殊类设计和单例模式的深入探讨,我们可以更好地设计和实现复杂的C++程序。特殊类设计提高了代码的安全性和可维护性,而单例模式则确保类的唯一实例性和全局访问性。理解并掌握这些高级设计技巧,对于提升C++编程水平至关重要。
39 16