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++知识库]类和对象————多态

.1多态的基本概念

  • 静态多态:函数重载以及运算符重载。函数地址早绑定–编译阶段确定函数地址
  • 动态多态派生类虚函数实现运行时多态。函数地址晚绑定–运行阶段确定函数地址
    动态多态满足条件:
    1.有继承关系
    2.子类重写父类中的虚函数
    3.父类的指针或引用,执行子类的对象
class Animal {
public:
	virtual void speak() {					//虚函数
		cout << "动物说话" << endl;
	}
};
class Dog :public Animal{					//继承
public :
	void speak(){
		cout << "狗说话" << endl;
	}
};

//父类的指针或者引用,执行子类的对象,
void dospeak(Animal &animal) {
	animal.speak();
}

void test() {
	Dog p;
	dospeak(p);					//想执行Dog的speak函数,函数地址需要在运行时确定
}

内部原理:
在这里插入图片描述
当子类重写父类函数时,会用子类虚函数表覆盖掉父类的虚函数表,从而在动态多态调用
在这里插入图片描述
指针实现多态:

class Calculator {
public :
	virtual int getre() {
		return 0;
	}
	int m_num1;
	int m_num2;

};

class add : public Calculator {
public:
	int getre() {
		return m_num1 + m_num2;
	}
};

class sub : public Calculator {
public:
	int getre() {
		return m_num1 - m_num2;
	}
};

void test() {
	Calculator* abs = new add;			//父类的指针指向子类的对象
	cout << abs->getre() << endl;
	delete abs;
}

.2纯虚函数和抽象类

由于在多态中,父类中虚函数实现无意义,可以改成纯虚函数virtual 返回类型 函数名 (参数) = 0;
同时父类称为抽象类
抽象类特点:

  1. 无法实例化对象
  2. 抽象类的子类必须重写父类中的纯虚函数,否则也属于抽象类
    实例:
class Abs {
public :
	virtual void step1() = 0;
	virtual void step2() = 0;
	
	void getresult() {
		step1();
		step2();
	}
};

class Son1 :public Abs {
public:
	void step1() {
		cout << "Son1执行第一步" << endl;
	}
	void step2() {
		cout << "Son1执行第二步" << endl;
	}
};
	
void test() {
	Abs* p = new Son1;
	p->getresult();
	delete p;
}

.3虚析构和纯虚析构

使用多态时,如果子类中有属性开辟到堆区,父类指针释放时无法调用子类析构代码

class Abs {
public :
	Abs() {
		cout << "Abs构造函数调用" << endl;
	}


	~Abs() {
		cout << "Abs析构函数调用" << endl;
	}

};

class Son :public Abs {
public:
	Son(string name) {
		cout << "son构造函数调用" << endl;
		m_name = new string(name);
	}
	~Son() {
		cout << "son析构函数调用" << endl;
		if (m_name != NULL) {
			delete m_name;
			m_name = NULL;
		}
	}
	string* m_name;
};

void test() {
	Abs* p = new Son("zsd");
	delete p;
}

在这里插入图片描述
子类堆区数据未释放,有两种方法解决:

class Abs {
public :
	Abs() {
		cout << "Abs构造函数调用" << endl;
	}
	//虚析构只需要声明
	virtual ~Abs() = 0 ;
};
//2
class Abs {
public :
	Abs() {
		cout << "Abs构造函数调用" << endl;
	}
	//纯虚析构
	virtual ~Abs() = 0 ;
};
Abs::~Abs() {
	//需要实现
}

总结:
1.虚析构或纯虚析构是用来解决通过父类指针释放子类对象
2.如果子类中没有堆区数据,可以不写
3.拥有纯虚析构函数的类也属于抽象类

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-02-28 15:10:05  更:2022-02-28 15:13:33 
 
开发: 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 7:51:04-

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