当前位置: 首页 > article >正文

c++进阶---c++三大特性之一---多态

多态的简单介绍:是一种动态的访问函数,比如:你定义了一个一个人类和一个学生类,当你传入的是学生类的时候,你需要有购物优惠,这种情境下用多态就很适用。

1.简单的多态使用:

1.1构造多态的条件:

(1)子类和父类中有同名函数,返回值,参数均相同(构成重写)

(2)基类的函数必须用virtual限定,子类可以不用,但是要注意下面代码的情况

(3)在使用多态的时候,需要使用基类去访问

1.2使用多态的一个小例子

#include <iostream>
class A {
public :
	virtual void fun(int val = 1) {
		std::cout << "A->" << val << std::endl;
	}
	virtual void test() {
		fun();
	}
};
class B:public A{
public:
	void fun(int val = 0) {
		std::cout << "B->" << val << std::endl;
	}
};
int main() {
	B* p = new B;
	p->test();
	return 0;
}

这个代码打印的结果是B->1;

让我们详细地走这个代码的允许过程:

首先使用 new B创建了一个B对象,但是因为B没用显示构造,所以直接使用默认构造(同理基类)然后把B对象的地址给了指针P,然后访问test(),因为在B中没有test函数,所以就传了A的this进去A类中找,成功找到test(),又需要去走fun(),因为现在的this指针是A类的,又fun()均用virtual修饰了,所以构成多态,但是这里又有一个大坑,就是派生类没有使用virtual修饰(正常是需要修饰的),派生类的函数就变成了virtual void fun(int val=1)直接把基类的完成拷贝了一份下来。

2.虚函数:

2.1虚函数的简单介绍

在上面的例子中,出现了virtual关键字,在对象成员函数前面加这个的函数就叫做虚函数,虚函数主要是为了用于实现多态。

2.2虚函数的重写(覆盖)和重定义

当子类和父类中函数的返回值和参数均一致,且父类有virtual时就会构成重写,当子类或者父类中出现一个虚函数,另外一个出现一个不是虚函数的对应函数称之为重定义。

2.3两个与重写相关的关键字

2.3.1 override

把这个放在派生类重写的函数后,如果没有构成重写,就会报错。

2.3.2 final

如果把这个放在基类虚函数的后面,就会限定它不能被重写。

2.4析构函数的多态使用

为什么析构函数最好就要构成多态?

如果不构成多态的话,那么怎么使用p3子类的析构函数?

所以析构需要构造多态!

3.纯虚函数与抽象类:

当你有一种类似于车这种类,这种类在现实中并没有实体,简单来说,现实中是不是说的车都是挂在品牌的?

class Car {
	virtual void fun() = 0;
};

这种情况下就有了纯虚函数的定义,也就是 =0的这个,有这个就是纯虚函数,这种类是无法实例出对象的,如果继承它的类没有对他进行重构,那也无法实例出对象。这种类就叫做抽象类。

那这个是怎么用呢?看下面的代码,注意一个地方,虽然无法实例化,但是可以使用指针,因为要构成多态!!

4.从底层来看这个虚函数和多态:

从代码可以看出,虚函数表是不同的,子类和父类均有属于自己的虚函数表,虚函数是在代码段的,虚函数表是在常量段的,很容易就能猜想到一个类定义多个对象共享一个虚函数表。

如何验证虚函数表是在常量段的?取字符串的地址和以下获取的地址进行比较。(虚函数指针数组一般都是在对应对象内存的开头,如果要看地址的时候可以*(int*)对象指针,先int*转化会变成4个字节的大小(x86)的指针,解引用就是函数虚表指针数组的第一个,再解引用就能取得其地址。)

根据这个虚函数指针数组也就能知道其怎么做到动态访问的:

你用子类剪切给父类对象去访问的时候,虚表还是子类的,访问虚函数不还是访问子类的?其次就是如果没有虚函数概念的话,那显然就是该访问啥访问啥


http://www.kler.cn/a/514598.html

相关文章:

  • 深度学习笔记——循环神经网络RNN
  • [Effective C++]条款48 模板元编程(TMP)
  • 快手SDK接入错误处理经验总结(WebGL方案)
  • 安装 uv
  • 【重庆市乡镇界】面图层shp格式arcgis数据乡镇名称和编码wgs84坐标无偏移内容测评
  • C++经典例题
  • 【蓝桥杯】43691.拉马车
  • SpringBoot项目中的异常处理
  • RV1126+FFMPEG推流项目源码
  • 浅谈微积分与e^x理解
  • 【机器学习】深入无监督学习分裂型层次聚类的原理、算法结构与数学基础全方位解读,深度揭示其如何在数据空间中构建层次化聚类结构
  • ”彩色的验证码,使用pytesseract识别出来的验证码内容一直是空“的解决办法
  • 2025 年了,你的科研工具箱更新了哪些新工具?
  • 账号IP属地:依据手机号还是网络环境?
  • DeepSeek系列
  • 顺序表和链表(详解)
  • KNN算法原理(深入浅出)
  • nvm版本安装
  • IP协议特性
  • 澎峰科技计算软件栈与沐曦GPU完成适配和互认证
  • 2000-2010年各省第三产业就业人数数据
  • 【单层神经网络】快速入门AI系列
  • 超大型集团合并报表数智管理转型
  • C语言基础------练习1
  • 相机内参的作用原理
  • doris:Stream Load