C++ DAY06 c++多态

简介

一个事物的多种形态 , 简称多态
物的多态
同一个人在不同人面前展现是不同的
:
        在我面前
        在对象面前
        在朋友面前
        在父母面前
事的多态
吃饭
        中国人 筷子 熟食
        美国人 刀叉 7 分熟
        日本人 筷子 生食
        印度人 手
睡觉
        中国人 床上
        日本人 榻榻米
        侧卧
        平躺
        趴着

上行与下行

上行

子类转父类
语法
        父类名 * 父类对象指针 = 子类对象指针 ;
        父类名& 父类对象名 = 子类对象 ;
注意 :
        无风险, 无需强转

下行

父类转换为子类
语法
        子类名 * 子类对象指针 = ( 子类名 *) 父类对象指针 ;
        子类名& 子类对象 = ( 子类名 &) 父类对象 ;
注意 :
        有风险, 需强转

重写

重载

        同一作用域下, 函数名形同相同 ,形参列表不同        

重定义

        函数继承时,继承关系中,函数名相同即可

重写

        继承关系中,返回值类型相同,函数名形同,形参列表相同,函数体不同

c++多态分类

静态多态 ( 早绑定 , 静态联编 )
        概念:在编译阶段 就确定函数的入口地址.
        又名: 静态联编 , 早绑定
        如: 函数重载 , 运算符重载 , 重定义等
动态多态 ( 晚绑定 , 动态联编 )
        概念: 在运行阶段确定程序入口地址
        又名: 动态联编 , 晚绑定
        如: 虚函数 , 重写

引入

要求 : 设计一个函数 , 根据传入的对象调用重写的方式
代码
#include <iostream>
using namespace std;
class Anim{
public:void test01(){cout << "动物test01" << endl;}
};
class Dog:public Anim{
public:void test01(){cout << "狗类test01" << endl;}
};
class Cat:public Anim{
public:void test01(){cout << "猫类test01" << endl;}
};
void method01(Anim& a)
{
a.test01();
}
int main(int argc, char *argv[])
{Dog d;Cat c;method01(d);method01(c);return 0;
}
运行结果
原因
        父类指针只能操作子类空间中的父类部分。

虚函数

概念

        virtual修饰的成员函数 , 就是虚函数

语法    

virtual 返回值类型 函数名 ( 形参列表 )
{
        方法体
}

特点

当子类转换为父类后
使用该父类调用使用 virtual 修饰的函数 , 调用的是子类重写后的
使用该父类调用普通函数 , 调用的是父类的该函数

补充概念

重写 : 在继承关系中 , 子类方法与父类方法 , 返回值类型一致 , 函数名相同 , 形参列表相同
注意 : 子类重写父类虚函数 , 子类该函数默认为虚函数

代码

#include <iostream>
using namespace std;
class Anim{
public:virtual void test01(){cout << "动物test01" << endl;}
};
class Dog:public Anim{
public:void test01(){cout << "狗类test01" << endl;}
};
class Cat:public Anim{
public:void test01(){cout << "猫类test01" << endl;}
};
void method01(Anim& a)
{a.test01();
}
int main(int argc, char *argv[])
{Dog d;Cat c;method01(d);method01(c);return 0;
}

动态绑定条件(重要)

有继承,子类重写父类的虚函数,父类指针或引用指向子类空间。父类指针或引用才能调用子类重写的虚函数。
错误演示
        B b;
        //此时会调用父类的拷贝构造 , 会产生一个新的父类对象 , 该父类对象 a 与子类对象b是两个独立空间 ,所以此时使用a 对象调用 test01 依据会执行父类的 test01 函数
        //A a = b;
        A& a = b;
        a.test01();

动态绑定原理(重要)

父类有虚函数,产生虚函数指针指向虚函数表,表中纪录的是父类的虚函数地址。
如果子类继承父类,那么子类会继承父类的虚函数指针以及虚函数表。
如果子类重写父类的虚函数,会将将虚函数表纪录的入口地址修改成子类重写的函数入口地址。
这时父类指针指向子类空间,父类指针调用虚函数就间接调用子类重写的虚函数。

纯虚函数

概念

        父类的虚函数没有函数体

语法

        virtual 返回值类型 函数名(形参列表) = 0;

示例

#include <iostream>
using namespace std;
class Anim{
public:
//纯虚函数virtual void test01() = 0;
};
class Dog:public Anim{
public:void test01(){cout << "狗类test01" << endl;}
};
class Cat:public Anim{
public:void test01(){cout << "猫类test01" << endl;}
};
void method01(Anim& a)
{a.test01();
}
int main(int argc, char *argv[])
{Dog d;Cat c;method01(d);method01(c);return 0;
}

注意

纯虚函数所在的类不能直接创建对象 , 这种类被称为抽象类
子类继承与抽象类 , 要么重写父类提供的所有纯虚函数 , 要么自己也是抽象类

虚析函数

引入

#include <iostream>
using namespace std;
class Anim{
public:virtual void test01() = 0;Anim(){cout << "父类构造" << endl;}~Anim(){cout << "父类析构" << endl;}
};
class Dog:public Anim{
public:void test01(){cout << "狗类test01" << endl;}Dog(){cout << "子类Dog构造" << endl;}~Dog(){cout << "子类Dog析构" << endl;}
};
int main(int argc, char *argv[])
{Dog *d = new Dog();Anim *a = d;delete a;return 0;
}

结果

        问题: 没有子类析构函数调用
        解决方案: 将父类的析构函数 设置成 虚析构

语法

virtual ~ 析构函数 ()
{
}

代码

#include <iostream>
using namespace std;
class Anim{
public:virtual void test01() = 0;Anim(){cout << "父类构造" << endl;}virtual ~Anim(){cout << "父类析构" << endl;}
};
class Dog:public Anim{
public:void test01(){cout << "狗类test01" << endl;}Dog(){cout << "子类Dog构造" << endl;}~Dog(){cout << "子类Dog析构" << endl;}
};
int main(int argc, char *argv[])
{Dog *d = new Dog();Anim *a = d;delete a;return 0;
}

结果:

纯虚析构(了解)

语法

        virtual 析构函数名 () = 0;

注意

        需要在类外实现析构函数

#include <iostream>
using namespace std;
class Anim{
public:virtual void test01() = 0;Anim(){cout << "父类构造" << endl;}virtual ~Anim() = 0;
};
Anim::~Anim()
{cout << "父类析构" << endl;
}
class Dog:public Anim{
public:void test01(){cout << "狗类test01" << endl;}Dog(){cout << "子类Dog构造" << endl;}~Dog(){cout << "子类Dog析构" << endl;}
};
int main(int argc, char *argv[])
{Dog *d = new Dog();Anim *a = d;delete a;return 0;
}

结果

总结

1、虚函数和纯虚函数的区别?
        虚函数和纯虚函数都是为了通过父类指针调用子类重写的虚函数。
        虚函数 不=0 修饰 , 有函数体 , 所在的类不是抽象类 , 可以实例化对象。
        纯虚函数 =0 修饰 , 没有函数体 , 所在的类是抽象类 , 不可以实例化对象。
2、虚析构和纯虚析构的区别
        虚析构和纯虚析构都是为了通过父类指针释放子类的所有空间( 父类部分 , 子类部分 )
        虚析构不=0 修饰 , 所在的类不是抽象类 , 可以实例化对象。
        纯虚析构=0 修饰 , 类外实现函数体 , 所在的类是抽象类 , 不可以实例化对象。
3、重载、重定义、重写的区别
        重载:没有继承,函数重载和运算符重载。函数名相同,参数的个数,顺序、类型可以不同,返回值类型不能作为重载条件。
        重定义:有继承,子类重定义父类同名函数(非虚函数)。返回值类型,形参可以相同 和 不同。
        重写:有继承,子类重写父类的虚函数。函数名,返回值类型,形参必须和父类同名函数一致。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/199676.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【U8+】用友U8账套引入/还原,提示:逻辑文件‘UFModel’不是数据库的一部分。

【问题描述】 用友U8+账套引入(恢复账套)的时候,提示: 逻辑文件‘UFModel’不是数据库‘UFDATA_001_2015’的一部分。 请使用RESTORE FILELISTONLY来列出逻辑文件名。-2147217900 【解决方法】 查看用友U8+账套库正确的逻辑名称为【UFMODEL】和【UFMODEL_log】。 【案例…

​分享mfc140u.dll丢失的解决方法,针对原因解决mfc140u.dll丢失的问题

作为电脑小白&#xff0c;如果电脑中出现了mfc140u.dll丢失的问题&#xff0c;肯定会比较的慌乱。但是出现mfc140u.dll丢失的问题&#xff0c;其实也有很简单的办法&#xff0c;所以大家不用慌张&#xff0c;接下来就教大家解决办法&#xff0c;能够有效的解决mfc140u.dll丢失的…

MFC 对话框

目录 一、对话款基本认识 二、对话框项目创建 三、控件操作 四、对话框创建和显示 模态对话框 非模态对话框 五、动态创建按钮 六、访问控件 控件添加控制变量 访问对话框 操作对话框 SendMessage() 七、对话框伸缩功能实现 八、对话框小项目-逃跑按钮 九、小项…

C#中的is和as的使用和区别

目录 概述一、is操作符1. is操作符的语法2. is操作符的用途3. is操作符的使用示例4. is操作符与typeof操作符的区别 二、as操作符1. as操作符的语法2. as操作符的用途3. as操作符的使用示例4. as操作符与is操作符的区别和联系5. as操作符与is操作符的区别总结 概述 在C#编程语…

探寻欧洲市场的机遇:深度剖析欧洲跨境电商

随着全球化的不断推进&#xff0c;欧洲作为一个经济发达、多元文化共存的大陆&#xff0c;成为跨境电商发展的重要目标。本文将深入剖析欧洲跨境电商的机遇&#xff0c;分析欧洲市场的特点、挑战与前景&#xff0c;为企业提供在这个充满潜力的市场中蓬勃发展的指导。 欧洲市场的…

【前端学java】java中的Object类(8)

往期回顾&#xff1a; 【前端学java】JAVA开发的依赖安装与环境配置 &#xff08;0&#xff09;【前端学 java】java的基础语法&#xff08;1&#xff09;【前端学java】JAVA中的packge与import&#xff08;2&#xff09;【前端学java】面向对象编程基础-类的使用 &#xff08…

YOLOv8-Seg改进:位置信息的轴线压缩增强注意力Sea_Attention| ICLR2023 SeaFormer,轻量级语义分割算法,复旦大学和腾讯

🚀🚀🚀本文改进:位置信息的轴线压缩增强注意力Sea_Attention,一方面将QKV特征进行轴线压缩后再注意力增强,另一方面将QKV特征使用卷积网络提升局部信息,最后将二者融合,输出增强特征 🚀🚀🚀Sea_Attention小目标分割首选,暴力涨点 🚀🚀🚀YOLOv8-seg创新…

LeetCode【76】最小覆盖子串

题目&#xff1a; 思路&#xff1a; https://segmentfault.com/a/1190000021815411 代码&#xff1a; public String minWindow(String s, String t) { Map<Character, Integer> map new HashMap<>();//遍历字符串 t&#xff0c;初始化每个字母的次数for (int…

redis 非关系型数据库

redis 非关系型数据库&#xff0c;缓存型数据库。 关系型数据库和非关系型数据库的区别 关系型数据库是一个机构化的数据库&#xff0c;行和列。 列&#xff1a;声明对象 行&#xff1a;记录对象属性。 表与表之间是有关联&#xff0c;使用sql语句&#xff0c;来对指定的表…

【Linux】指令详解(二)

目录 1. 前言2. 重新认识指令2.1 指令的本质2.1.1 which2.1.2 alias 3. 常见指令3.1 whoami3.2 cd3.2.1 cd -3.2.2 cd ~ 3.3 touch3.3.1 文件创建时间 3.4 stat3.5 mkdir3.5.1 创建一个目录3.5.2 创建路径 3.6 tree3.7 rm3.7.1 rm -f3.7.2 rm -r 3.8 man3.9 cp3.10 mv 1. 前言 …

键盘快捷键工具Keyboard Maestro mac中文版介绍

Keyboard Maestro mac是一款键盘快捷键工具&#xff0c;它可以帮助用户通过自定义快捷键来快速完成各种操作&#xff0c;提高工作效率。Keyboard Maestro支持多种快捷键组合&#xff0c;包括单键、双键、三键、四键组合等&#xff0c;用户可以根据自己的习惯进行设置。此外&…

扩散模型实战(十):Stable Diffusion文本条件生成图像大模型

推荐阅读列表&#xff1a; 扩散模型实战&#xff08;一&#xff09;&#xff1a;基本原理介绍 扩散模型实战&#xff08;二&#xff09;&#xff1a;扩散模型的发展 扩散模型实战&#xff08;三&#xff09;&#xff1a;扩散模型的应用 扩散模型实战&#xff08;四&#xff…

【智能家居】5、主流程设计以及外设框架编写与测试

目录 一、主流程设计 1、工厂模式结构体定义 &#xff08;1&#xff09;指令工厂 inputCmd.h &#xff08;2&#xff09;外设工厂 controlDevices.h 二、外设框架编写 1、创建外设工厂对象bathroomLight 2、编写相关函数框架 3、将浴室灯相关操作插入外设工厂链表等待被调…

揭开副业的神秘面纱,上班摸鱼搞副业

副业没那么神秘&#xff0c;说白了就是销售。 卖文字、卖知识、卖技能、卖产品 ... 找对了渠道&#xff0c;有人愿意买单&#xff0c;就成了副业。 但是现在搞副业&#xff0c;坑多水深的&#xff0c;太多人栽跟头了&#xff0c;丢几百块都能算少的。 开始细说干货之前&#…

DCDC同步降压控制器SCT82A30\SCT82630

SCT82A30是一款100V电压模式控制同步降压控制器&#xff0c;具有线路前馈。40ns受控高压侧MOSFET的最小导通时间支持高转换比&#xff0c;实现从48V输入到低压轨的直接降压转换&#xff0c;降低了系统复杂性和解决方案成本。如果需要&#xff0c;在低至6V的输入电压下降期间&am…

生产环境_移动目标轨迹压缩应用和算法处理-Douglas-Peucker轨迹压缩算法

场景&#xff1a; 我目前设计到的场景是&#xff1a;即在地图应用中&#xff0c;对GPS轨迹数据进行压缩&#xff0c;减少数据传输和存储开销&#xff0c;因为轨迹点太频繁了&#xff0c;占用空间太大&#xff0c;运行节点太慢了&#xff0c;经过小组讨论需要上这个算法&#x…

NGINX缓存详解之服务端缓存

服务端缓存 proxy cache属于服务端缓存,主要实现 nginx 服务器对客户端数据请求的快速响应。 nginx 服务器在接收到被代理服务器的响应数据之后,一方面将数据传递给客户端,另一方面根据proxy cache的配置将这些数据缓存到本地硬盘上。 当客户端再次访问相同的数据时,nginx…

Virtual安装centos后,xshell连接centos 测试及遇到的坑

首先来一张官方的图--各种网络模式对应的连接状况&#xff1a; 1. 网络使用Host-Only模式动态分配IP&#xff0c;点确定后&#xff0c;centos 上运行 system restart network &#xff0c;使用ifconfig查看新的ip&#xff0c;XShell可以直接连上centos&#xff0c; 但是由于使用…

美国费米实验室SQMS启动“量子车库”计划!30+顶尖机构积极参与

​11月6日&#xff0c;美国能源部费米国家加速器实验室(SQMS)正式启动了名为“量子车库”的全新旗舰量子研究设施。这个6,000平方英尺的实验室是由超导量子材料与系统中心负责设计和建造&#xff0c;旨在联合国内外的科学界、工业领域和初创企业&#xff0c;共同推动量子信息科…

裸片-PCBA

裸片 PCBA&#xff0c; 薄膜&#xff0c; 邦定-COB&#xff08;chip on board&#xff09;技术是指将裸芯片直接贴在PCB 板上&#xff0c;然后用铝线或金线进行电子连接的技术