IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++特性:多态、重写 -> 正文阅读

[C++知识库]C++特性:多态、重写

说一下多态

多态就是不同的继承类对象,针对同一消息做出不同的响应,父类的指针指向或者绑定到子类的对象,使得父类指针呈现多种不同的表现方式。
要实现多态,首先父类需要有一个virtual修饰的虚方法,子类要重写父类的虚方法。父类的指针绑定子类的对象。
多态是通过虚函数表实现的,调用虚方法时,父类指针指向子类的虚表指针,虚表指针指向子类的虚函数表,通过遍历子类的虚函数表,找到对应的虚方法。
由于子类对象重写的父类的虚方法,在虚函数表中达成覆盖,所以通过父类的指针就可以调用子类的方法。从而达到多态。

多态概念

通俗来说,多态就是多种形态,具体点就是去完成某种行为,不同的类去完成就会产生不同的形态。
比如一个Active方法,包含了吃、走、爬、飞等行为,当调用这个方法,蜗牛就是爬,鸟就是飞。

class Base
{
	virtual void fun(){}
	virtual Base* fun(){}   //重载,也是重写的例外之一
	virtual ~Base()     //重写的例外之二
}
class D : public Base
{
	virtual void fun(){}     //重写,三同
	virtual Base* fun(){}    //返回值不同,重写的例外
	virtual ~D(){}           //析构多态,函数名不同,重写的例外
}

虚方法

被virtual修饰的类成员方法就是虚方法/虚函数
一个类中有了虚方法就会增加虚表指针存放虚方法的地址
在内存中多占一个空间。

多态的定义和实现

多态的条件:

  • 父类有virtual虚方法
  • 子类重写了父类的虚方法
  • 通过父类的指针/引用接收不同的子类(向上转换)

重载、重写、隐藏

重载:

class A
{
//函数名相同
//参数(个数或类型或顺序)或返回值不同
public:
	void fun(){}
	void fun(int a){}
	void fun(int a,int b){}
	int  fun(){}
}

同名隐藏:

class A
{
public:
	void fun();
}
class Bpublic A
{
//同名隐藏,用父类指针调用fun方法,调用的是子类的方法
//但可以通过作用域声明来调用父类的fun A::fun()
//只要子类方法和父类函数名相同,其他什么都不管,就是同名隐藏
public:
	void fun(){}    //三同就是重写/覆盖
	int fun(int a){}
}

重写

class A
{
public:
	void fun();
}
class Bpublic A
{
public:
	//函数名相同,返回值相同,参数列表相同
	void fun(){}    //三同就是重写/覆盖
}

重写例外:

协变

class A
{
public:
	A* fun();
}
class Bpublic A
{
public:
	//函数名相同,参数列表相同,但返回值不同
	B* fun(){} 
}

返回值不同,父类返回父类指针/引用,子类返回子类指针/引用,这是可以达成重写的。
原因是,继承赋值兼容规则的向上转换。
析构方法重写/析构多态
当使用父类指针接收子类对象时,Base* pb = new D;构造没有任何问题,delete D析构时却会产生问题,由于D这块空间给了父类指针,那么pb只能观察到父类所在的范围,就不会去调用子类的析构方法,这就有可能导致子类申请的空间来不及释放或不能释放,造成内存泄漏。
给父子类析构方法加上virtual变成虚方法,就可以达成析构重写(函数名不同,所以是重写的例外),就可以调用到子类的析构方法。
在这里插入图片描述

单继承和多继承中虚函数表

Base类的虚函数表:

class Base { 
public: 
virtual void f() { cout << "Base::f" <<endl;}
virtual void g() { cout << "Base::g" <<endl;}
virtual void h() { cout << "Base::h" <<endl;}
}; 
//通过Base实例来获取虚函数表
typedef void(*Fun)(void); 
Base b; 
Fun pFun = NULL; 
cout << "虚函数表地址:" << (int*)(&b) <<endl;
cout << "虚函数表 — 第一个函数地址:" << (int*)*(int*)(&b) <<endl;
pFun = (Fun)*((int*)*(int*)(&b)); 
pFun(); 
//强制类型转换
(Fun)*((int*)*(int*)(&b)+0); // Base::f() 
(Fun)*((int*)*(int*)(&b)+1); // Base::g() 
(Fun)*((int*)*(int*)(&b)+2); // Base::h()

Base类对象的内存结构图:
在这里插入图片描述
单继承
未重写:

class A:public Base
{
	void f1() { cout << "A::f" <<endl;}
	void g1() { cout << "A::g" <<endl;}
	void h1() { cout << "A::h" <<endl;}
};

A实例的成员内存图
在这里插入图片描述
重写:

class A:public Base
{
	virtual void f() { cout << "A::f" <<endl;}
	void g1() { cout << "A::g" <<endl;}
	void h1() { cout << "A::h" <<endl;}
};

A类实例的成员内存图:
在这里插入图片描述

多继承:
无覆盖:

class A:public Base1,public Base2,public Base3
{
	void f1() { cout << "A::f" <<endl;}
	void g1() { cout << "A::g" <<endl;}
	void h1() { cout << "A::h" <<endl;}
};

在这里插入图片描述

有覆盖:

class A:public Base1,public Base2,public Base3
{
	virtual void f() { cout << "A::f" <<endl;}
	void g() { cout << "A::g" <<endl;}
	void h() { cout << "A::h" <<endl;}
};

在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-13 22:34:39  更:2022-04-13 22:58:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:30:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码