C++中的覆盖和隐藏详解

 更新时间:2021年08月31日 18:05:29   作者:Nogup  
这篇文章主要介绍了C++中重载、重写(覆盖)和隐藏的区别,是C++面向对象程序设计非常重要的概念,需要的朋友可以参考下,希望能够给你带来帮助

1. 前言

继承是面向对象编程的重要特性,在c++中,当父类与子类出现同名函数时,会出现两种情况:覆写和隐藏,本文主要讨论c++中这两种情况的特点和使用区别

2. 共性

当子类继承父类,并且子类中有父类同名函数,那么子类将隐藏父类中所有同名函数,不可以对父类中同名函数直接进行访问,此时子类调用父类中函数需要用域操作符::

#include<iostream>
using namespace std;
class A{
	public:
		void fun1(){
			cout<<"A::fun1()"<<endl;
		}
		void fun1(int){
			cout<<"A::fun1(int)"<<endl;
		}
		void fun2(){
			cout<<"A::fun2()"<<endl;
		}
};
class B:public A{
	public:
		void fun1(){
			cout<<"B::fun1()"<<endl;
		}
};
int main(){
	B b;
	b.fun1();//调用子类b的fun1()函数
    //b.fun1(3);尝试调用父类fun1(int)函数会报错:error:no matching function for call to 'B::fun1(int)'
	b.A::fun1();//调用父类A的fun1()函数
	b.A::fun1(3);//调用父类A的fun1(int)函数
	b.fun2();//调用父类A的fun2()函数
	return 0;
}

b调用fun1()函数,会调用子类b的fun1()函数,而尝试使用b.fun(3)调用父类的void fun(int)函数时,会报错,因为父类中的同名函数都被隐藏。此时调用父类中函数的方法是使用域操作符::。

当父类中同名函数拥有virtual修饰符修饰时,此时子类对父类函数进行覆写

#include<iostream>
using namespace std;
class A{
	public:
		virtual void fun1(){
			cout<<"A::fun1()"<<endl;
		}
		void fun1(int){
			cout<<"A::fun1(int)"<<endl;
		}
		void fun2(){
			cout<<"A::fun2()"<<endl;
		}
};
class B:public A{
	public:
		virtual void fun1(){
			cout<<"B::fun1()"<<endl;
		}
};
int main(){
	B b;
	b.fun1();//调用子类b的fun1()函数
    //b.fun1(3);尝试调用父类fun1(int)函数会报错:error:no matching function for call to 'B::fun1(int)'
	b.A::fun1();//调用父类A的fun1()函数
	b.A::fun1(3);//调用父类A的fun1(int)函数
	b.fun2();//调用父类A的fun2()函数
	return 0;
}
 

可见即使是虚函数覆写,也会隐藏父类中的所有同名函数。

当子类与父类有同名函数,无论是覆写还是隐藏的方式,在子类自身进行函数调用时,会调用子类函数而隐藏父类的所有同名函数,要访问父类函数需要通过域操作符进行访问。

3. 区别

覆写与隐藏的区别可以体现在基类指针的使用上,比如以下程序

#include<iostream>
using namespace std;
class A{
	public:
		void function1(){
			cout<<"A::function1"<<endl;
		}
		virtual void function2(){
			cout<<"A::function2"<<endl;
		}
};
class B:public A{
	public:
		//隐藏基类function1
		void function1(){
			cout<<"B::function1"<<endl;
		}
};
class C:public A{
	public:
		//覆写基类function2
		virtual void function2(){
			cout<<"C::function2"<<endl;
		}
};
int main(){
	A *a;
	B b;
	C c;
	a=&b;
	a->function1();
	a=&c;
	a->function2();
	return 0;
}

b隐藏基类的同名函数function1(),当基类指针a指向子类b时,调用的是a的function1()函数,而子类c覆写a的同名函数function2(),当基类a指针指向子类c,调用的是c的function2()函数。

利用覆写的特点,可以实现c++的多态特性。

4. 区分

隐藏:当父类函数与派生类函数同名,并且父类函数无virtual关键字修饰,无论父类与派生类参数个数与类型是否相同,此时派生类函数隐藏父类所有同名函数

覆写:当父类函数与派生类函数同名,并且参数相同,返回值相同,并且父类函数有virtual关键字修饰,此时派生类函数覆写父类函数

5.参考文章

C++继承中的重载,覆盖和隐藏

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • C++中日期类的常见题目合集分享

    C++中日期类的常见题目合集分享

    这篇文章主要为大家详细介绍了一些C++中日期类的常见题目,文中的示例代码讲解详细,对我们掌握C++有一定的帮助,感兴趣的小伙伴可以了解一下
    2023-06-06
  • C++中std::allocator的使用案例详解

    C++中std::allocator的使用案例详解

    这篇文章主要介绍了C++中std::allocator的使用案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-09-09
  • C语言双指针多方法旋转数组解题LeetCode

    C语言双指针多方法旋转数组解题LeetCode

    这篇文章主要为大家介绍了C语言双指针使用多方法旋转数组题解LeetCode,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-02-02
  • vs2019配置C++版OpenCV的方法步骤

    vs2019配置C++版OpenCV的方法步骤

    最近要用到很多OpenCV的库,所以开始学了点OpenCV,本文记录VS和OpenCV的安装、配置过程。具有一定的参考价值,感兴趣的可以了解一下
    2021-09-09
  • C++异常处理方式实例详解(超级详细!)

    C++异常处理方式实例详解(超级详细!)

    程序有时会遇到运行阶段错误,导致程序无法正常执行下去,c++异常为处理这种情况提供了一种功能强大的而灵活的工具,下面这篇文章主要给大家介绍了关于C++异常处理方式的相关资料,需要的朋友可以参考下
    2023-04-04
  • 获取本地网卡适配器信息具体代码

    获取本地网卡适配器信息具体代码

    这篇文章主要介绍了获取本地网卡适配器信息具体代码,有需要的朋友可以参考一下
    2013-12-12
  • C语言栈顺序结构实现代码

    C语言栈顺序结构实现代码

    一个能够自动扩容的顺序结构的栈 ArrStack 实例 (GCC编译),有需要的朋友可以参考一下
    2013-10-10
  • C语言二维数组指针的概念及使用

    C语言二维数组指针的概念及使用

    C语言中的二维数组是按行排列的,也就是先存放a[0]行,再存放a[1]行,最后存放a[2]行;每行中的4个元素也是依次存放。数组a为int类型,每个元素占用4个字节,整个数组共占用48个字节
    2023-02-02
  • C++ LeetCode543题解二叉树直径

    C++ LeetCode543题解二叉树直径

    这篇文章主要为大家介绍了C++ LeetCode543题解二叉树直径,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • C++实现多项式相乘

    C++实现多项式相乘

    这篇文章主要介绍了C++实现多项式相乘方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07

最新评论