博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++:多态
阅读量:2086 次
发布时间:2019-04-29

本文共 3029 字,大约阅读时间需要 10 分钟。

一.多态原理

静态多态:函数重载

动态多态:函数重写 virtual关键字
静态联编:地址早绑定,编译阶段绑定好地址
动态联编:在运行阶段确定函数地址
多态:父类的引用或者指针指向子类对象
原理:对于一个只有成员函数的类 其大小为1 如果给成员函数添加virtual关键字,则大小变为4,这是由于该类内部出现一个指针 vfptr 虚函数表指针,指向虚函数表中储存的指向该类内的成员函数的地址,如果该子类没有声明与父类virtual函数相同的同名函数,或者声明了与父类中没加virtual的同名函数,构造函数中,子类的vfptr会拥有与父类的虚函数表相同的虚函数表 指向&Animal::speak,有子类继承该父类时,如果使用与父类中virtual声明的同名函数,叫做重写,重写必须返回值 参数 类型 顺序都相同 ,子类会将自己虚函数表中的父类函数地址改为自己的函数地址,vfptr会指向子类自己的虚函数表中该函数的地址 &Cat::speak()

Animal *animal = new Cat;

animal.speak(); 父类指针指向子类对象 调用子类重写后的函数

class Animal{
public: virtual void speak() {
cout<<"Animal Speak"<

二.多态案例:计算器

真正的开发中,有个原则:开闭原则。

对扩展开放,对修改关闭。
使用多态 利于后期扩展 结构性好 可读性高 但是效率会变低 结构变复杂。
利用多态 在需要加入新的功能时,只需要添加相应的类即可。

普通虚函数:类内声明,类内实现,子类可以选择实现或者不实现。

纯虚函数:只声明,不实现,子类必须实现

如果父类有纯虚函数 子类中必须实现纯虚函数,否则该子类也是个抽象类(不能实例化对象)

如果父类有纯虚函数,该父类不能实例化对象
这个类有了纯虚函数,通常称为抽象类。

class abstractCalculator{
public: void setval1(int a) {
this->val1 = a; } void setval2(int b) {
this->val2 = b; }// //虚函数// virtual int getResult()// {
// return 0;// } //如果父类有纯虚函数 子类中必须实现纯虚函数,否则该子类也是个抽象类(不能实例化对象) //如果父类有纯虚函数,该父类不能实例化对象 //这个类有了纯虚函数,通常称为抽象类。 virtual int getResult() = 0; int val1; int val2;};class PulsCalculator:public abstractCalculator{
public: virtual int getResult() {
return val1 + val2; }};class SubCalculator:public abstractCalculator{
public: virtual int getResult() {
return val1 - val2; }};class subclass :public abstractCalculator{
public: int getResult() {
return 0; }};void test003(){
abstractCalculator* puls = new PulsCalculator; puls->setval1(10); puls->setval2(20); cout<
getResult()<
setval1(10); puls->setval2(20); cout<
getResult()<

三.虚析构和纯虚析构

1.虚析构

普通析构是不会调用子类的析构的,所以在使用父类指针指向子类对象时,释放时,可能导致子类释放不干净。

class Animal1{
public: virtual void speak() {
cout<<"animal speak"<
m_Name = new char[strlen(name)+1]; strcpy(this->m_Name,name); } ~Cat1() {
cout<<"Cat1 xigou"<
m_Name != NULL) {
delete[] m_Name; this->m_Name = NULL; } } virtual void speak() {
cout<<"cat speak"<
speak(); //查看调用了哪个析构 delete animal; //打印: Animal1 xigou //父类不使用虚析构时,调用了Animal1类的析构函数,不会调用子类的析构函数,和普通函数相同,所以需要父类使用虚析构函数}

2.纯虚析构

纯虚析构需要类内声明,类外实现

出现纯虚析构函数,该类也是抽象类,不可实例化
子类虚构函数必须实现,否则也是抽象类
使用父类指针指向子类对象时,如果父类使用纯虚析构函数,则在释放时,先析构子类,再析构父类。

//纯虚析构class Animal2{
public: virtual void speak() {
cout<<"animal speak"<
m_Name = new char[strlen(name)+1]; strcpy(this->m_Name,name); } ~Cat2() {
cout<<"Cat1 xigou"<
m_Name != NULL) {
delete[] m_Name; this->m_Name = NULL; } } virtual void speak() {
cout<<"cat speak"<
speak(); //查看调用了哪个析构 delete animal; // 打印:Cat1 xigou Animal2 Pure virtual destructor //先析构子类,再析构父类}

转载地址:http://dssqf.baihongyu.com/

你可能感兴趣的文章
【MyBatis学习15】MyBatis的逆向工程生成代码
查看>>
Java 中 final、finally 和 finalize 使用总结
查看>>
volatile关键字解析
查看>>
单例模式的八种写法比较
查看>>
比较常见的数据库SQL面试题以及答案
查看>>
MySQL与Oracle的区别
查看>>
关于Oracle数据库优化的几点总结
查看>>
69道Spring面试题和答案
查看>>
40个Java多线程问题总结
查看>>
Oracle数据库面试题
查看>>
java面试中的智力题
查看>>
本地如何连接hbase数据库
查看>>
Maven出错-Missing artifact org.apache.openejb:openejb-core:jar:4.1.0-SNAPSHOT:test
查看>>
dubbo配置文件xml校验报错
查看>>
eclipse生成export生成jar详解
查看>>
oracle 模糊查询忽略大小写
查看>>
Java项目导出可运行的jar文件
查看>>
Java文件夹操作,判断多级路径是否存在,不存在就创建(包括windows和linux下的路径字符分析),兼容Windows和Linux
查看>>
JAVA读取PROPERTIES配置文件
查看>>
Linux中执行shell脚本的4种方法总结
查看>>