C++总结笔记(九)—— 多态

文章目录

  • 一、多态是什么?
  • 二、使用步骤
    • 2.1. 静态多态
      • 2.1.1 函数重载
      • 2.1.2 模板
    • 2.2.动态多态
      • 2.2.1 示例
      • 2.2.2 原理分析
  • 总结


一、多态是什么?

多态是面向对象的语言中都必须掌握的特性,其概念简单讲就是对同一种特性的方法有不同的实现功能,例如玩手机这个方法,有人玩抖音,有人玩LOL等等种不同的应用形式。
多态可以按照绑定分为静态多态动态多态
绑定是指函数体与函数调用完成关联的过程。
静态多态是指在程序编译期间就完成,一般通过函数重载模板来完成,会根据函数实参的类型或个数来选择那个函数来实现。
动态多态是指在程序编译后完成的联编,通过虚方法的形式完成,根据引用对象的实际类型调用相应的方法。其原理就是用父类的虚函数指针去调用子类中被重写的方法

二、使用步骤

2.1. 静态多态

2.1.1 函数重载

下面为构造函数重载示例:

class Cat
{
public:Cat(){cout << "喵是无参构造函数" << endl;}Cat(string name){Name = name;cout << "喵是有参构造函数" << endl;}//用于拷贝c的属性值,用常量引用的方式进行Cat(const Cat &c){Name = c.Name;cout<< "喵是拷贝构造函数" << endl;}~Cat(){cout << "喵是析构函数" << endl;}string Name;//咪咪名字
};void FindName()
{//括号法Cat cat1;//用默认构造函数时,不能加括号,否则编译器会当作函数声明。Cat cat2(cat1);//拷贝构造函数调用Cat cat3("小300");//有参构造函数调用。Cat cat4(cat3);//拷贝构造函数调用cout << "第一个猫的名字是:" << cat1.Name << endl;cout << "第二个猫的名字是:" << cat2.Name << endl;cout << "第三个猫的名字是:" << cat3.Name << endl;cout << "第四个猫的名字是:" << cat4.Name << endl;
}

2.1.2 模板

模板在C++中分为类模板和函数模板,用template修饰,和泛型的概念很相似。

类模板是通过建立一个通用类,其中的数据成员、成员函数的返回值类型和形参类型不进行具体指定,用一个虚拟的类型声明。在使用类模板定义对象时,系统会实参的类型来取代类模板中虚拟类型从而实现了不同类的功能。

函数模板也需声明一个模板类名,然后在函数形参中声明一个模板类对象,在进行函数调用时会根据实参的类型来覆盖模板类。

函数模板调用规则:
1.如果函数模板和普通函数都可以实现功能的话优先调用普通函数。
2.可以通过空模板参数列表来强制调用函数模板。
3.函数模板可以发生重载。
4.如果函数模板可以产生更好的匹配,优先调用函数模板。

类模板和函数模板的区别:
1:类模板没办法对声明的模板类对象进行自动推导类型,必须用指定类型,函数模板可以。
2:类模板在模板参数声明时可以有默认参数类型,比如在声明构造函数时一个形参为模板类型,一个为int类型。

类模板

#include <iostream>
#include<string>
using namespace std;template<class T1, class T2>class Person
{
public:Person(T1 name, T2 age){this->m_age = age;this->m_name = name;}void showPerson(){cout << m_name <<" "<< m_age << endl;}private:T1 m_name;T2 m_age;
};int main()
{Person<string, int> p("张三", 1);p.showPerson();system("pause");return 0;
}

函数模板

#include <iostream>
using namespace std;template<class T>//T的类型需要一致,选择排序
void Sort(T arr[], int l)
{for (int i = 0; i < l; i++){int max = i;for (int j = i + 1; j < l; j++){if (arr[max] > arr[j]){max = j;}}if (max != i){T temp = arr[max];arr[max] = arr[i];arr[i] = temp;}}
}int main()
{int Array[] = {1,4,35,24,213,2132};int num = sizeof(Array) / sizeof(int);Sort(Array, num);//Sort<>(Array, num);//空模板参数列表for(int i = 0; i< num; i++){cout << Array[i] << endl;}system("pause");return 0;
}

2.2.动态多态

动态多态需满足以下条件:
1.类之间存在继承关系
2. 调用函数的对象必须是指针或者引用。
3.子类重写父类函数(函数返回值、名称和参数列表相同)

2.2.1 示例

#include<iostream>
using namespace std;class Student
{
public://虚函数virtual void play(){cout << "我在玩手机" << endl;}//纯虚函数,纯虚函数的类为抽象类,类无法实例化/*virtual void play() = 0;*///父类写虚析构函数virtual ~Student(){}
};class Student1 :public Student
{
public:Student1(string app){APP = new string(app);}void play(){cout << "我在刷" << *APP << endl;}//如果没有在堆区开辟内存的化,不用写~Student1(){if (APP != NULL){delete APP;APP = NULL;}}private:string *APP;
};class Student2 :public Student
{
public:Student2(string app){APP = new string(app);}void play(){cout << "我在玩" << *APP << endl;}~Student2(){if (APP != NULL){delete APP;APP = NULL;}}
private:string* APP;
};int main()
{//父类指针在调用自身的析构函数时,不会调用子类的析构,从而造成内存泄露,所以要改为虚析构的方法。Student* s1 = new Student1("抖音");s1->play();delete s1;Student* s2 = new Student2("LOL");s2->play();delete s2;
}

2.2.2 原理分析

同样可以使用开发者工具进行分析。
在这里插入图片描述
其中vfptr指的是虚函数指针,vftable指的是虚函数表,父类子类中均存在虚函数指针和表,其中指针指向虚函数表。在进行虚函数的重写时,就会产生子类的虚函数指针,通过声明父类指针或引用调用函数时,就会覆盖vftable中类名,指向对应子类中的重写方法。


总结

多态的概念使C++的编程非常灵活,需要特别注意开闭原则和内存管理。

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

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

相关文章

组件局域网中的无集线器、Windows XP、Windows 7、Windows 8的对等网

为什么要用对等网&#xff1f; 答&#xff1a;对等网采用分散管理的方式&#xff0c;网络中的每台计算机既作为客户机又可作为服务器来工作&#xff0c;每个用户都管理自己机器上的资源。 组建局域网中无集线器的对等网 组建局域网中Windows XP的对等网 组建局域网中Windows 7的…

阿里巴巴将赴NIPS 2017 3大事业部联袂展示AI全技能

被誉为国际顶级的机器学习和神经网络学术会议NIPS 2017将于12月4日-9日在美国加州长滩市举行。在本届会议上&#xff0c;阿里巴巴除有两篇论文入选Workshop并进行Oral和Poster形式报告外&#xff0c;3大技术事业部将连续3天&#xff08;5日-7日&#xff09;在阿里展区举行多场技…

360安全卫士加速球误关闭某个应用软件

近期因为工作原因须要使用金山快盘。但因为之前电脑上安装了360安全卫士&#xff0c;在使用加速球功能的时候&#xff0c;会出现&#xff0c;误关闭金山快盘的操作&#xff0c;怎么避免呢&#xff1f; 1、打开360主界面。找到安全防护中心&#xff0c;例如以下图&#xff1a; 2…

20145238-荆玉茗 《信息安全系统设计基础》第7周学习总结

20145238 《信息安全系统设计基础》第7周学习总结 教材学习内容总结 存储器系统 : 存储器系统是一个具有不同容量、成本和访问时间的存储设备的层次结构。 1、RAM随机访问存储器 分类&#xff1a;SRAM&#xff08;静态&#xff09;、DRAM&#xff08;动态&#xff09;特点&…

关于两个jar包中存在包名和类名都完全相同的jar包冲突问题

2019独角兽企业重金招聘Python工程师标准>>> 最近弄webservice&#xff0c;我使用的jdk自带的wsimport工具来生成客户端代码&#xff0c;发现生成的代码具有编译错误&#xff0c;错误描述如下&#xff1a; The method getPort(QName, Class<T>) in the type S…

const和define 区别

1&#xff1a; 编译器处理不同 define宏是在预处理阶段展开&#xff0c;const常量是编译运行阶段使用。 2&#xff1a;类型和安全检查不同 const常量有数据类型&#xff0c;而宏常量没有数据类型&#xff0c;仅仅是展开。编译器可以对前者进行类型安全检查&#xff0c;而对后者…

【项目实战】——Python打包正装换底色代码为exe文件(可在其他无Python环境下运行)

目录 1.安装pyinstaller 2.生成.exe文件 方法1&#xff1a; 方法2&#xff1a; 方法3&#xff1a; &#xff08;1&#xff09;使用命令行窗口进入项目的根目录 &#xff08;2&#xff09;在改目录下执行pyi-makespec main.py&#xff08;main.py是你的主入口文件&#x…

安装完最小化 RHEL/CentOS 7 后需要做的 30 件事情(三)码农网

12. 安装 Apache Tomcat Tomcat 是由 Apache 设计的用来运行 Java HTTP web 服务器的 servlet 容器。按照下面的方法安装 tomcat&#xff0c;但需要指出的是安装 tomcat 之前必须先安装 Java。 # yum install tomcat 安装 Apache Tomcat 安装完 tomcat 之后&#xff0c;启动 to…

QT5.14.2基于PCL1.11.1显示点云(基于Windows VS2019开发环境)

文章目录一、安装1.1 PCL安装1.2 QT安装1.3 VTK编译二、程序配置1. 基于mscv创建QT的程序2. 配置QT工程文件和依赖项3. 编写点云显示的小程序总结一、安装 1.1 PCL安装 PCL1.11.1库的安装网上教程很多&#xff0c;推荐一个很好的教程&#xff1a; Win10 系统下 VisualStudio2…

Spring学习笔记—最小化Spring XML配置

自动装配(autowiring)有助于减少甚至消除配置<property>元素和<constructor-arg>元素&#xff0c;让Spring自动识别如何装配Bean的依赖关系。 自动检测(autodiscovery)比自动装配更进了一步&#xff0c;让Spring能够自动识别哪些类需要被配置成Spring Bean&#xf…

【数据结构】——快速排序

目录 一、代码 二、复杂度&#xff1a;O(nlog(n)) 三、快速排序的劣势 视频参考链接&#xff1a;https://www.bilibili.com/video/BV1mp4y1D7UP?p17 一、代码 思想&#xff1a;假设是对一个list进行排序 1、选取第一个元素作为p元素&#xff1b; 2、将p元素归位&#xff0…

读取数据库信息构建视图字段的备注信息,方便程序代码生成

在很多情况下&#xff0c;我们开发都需要有一个快速的代码生成工具用来提高开发效率&#xff0c;代码生成工具很多信息都是读取数据库的表、视图等元数据进行对象表信息的完善&#xff0c;有了这些信息&#xff0c;我们就可以在普通的实体类代码里面添加属性字段的中文注释&…

微博分享错误

昨天再做这块的时候&#xff0c;不知怎么的点击之后什么反应都没有&#xff0c;程序也没有崩&#xff0c;日志倒是输出了这个错误 解决办法&#xff1a;打开你写分享的代码跟API文档对比一下创建文本、图片或者网页的时候是不是少写了那个属性&#xff0c;我这里是在创建网页的…

代码生成工具之界面快速生成

界面开发&#xff0c;无论对于Web开发&#xff0c;还是Winform开发&#xff0c;都需要耗费一定的时间&#xff0c;特别对于一个数据库字段比较多的界面&#xff0c;一般就需要在编辑界面上摆的更多的控件来做数据显示&#xff0c;每次碰到这个&#xff0c;都有点头痛&#xff0…

javascript - 封装原生js实现ajax

1 /*2 * ajax方法3 */4 var Ajax function() {5 var that this;6 //创建异步请求对象方法7 that.createXHR function() {8 if(window.XMLHttpRequ…

QT对象树、信号和槽机制

文章目录一 、对象树是什么&#xff1f;二、信号和槽的基本概念2.1 信号2.2 槽2.3 松散耦合2.4 特点三、示例总结一 、对象树是什么&#xff1f; 对象树是由父类和若干子类对象组成&#xff0c;而子类也可以由若干孙类。 QT中的对象树是以QObject为起始父类来完成树的构建的&a…

【数据结构】——归并排序

目录 一、代码 二、随笔 一、代码 归并排序的主要思路&#xff1a;将两个有序的子列表归并为一个有序的大列表 #归并函数&#xff0c;假设li是由左右两个有序的子列表组成,假设两个子列表都是从小到大排好序的列表 def merge(li,low,mid,high)::param li: 由左右两个有序的子列…

开发发布npm module包

开发发布npm module包 问题 在项目开发过程中&#xff0c;每当进入一个新的业务项目&#xff0c;从零开始搭建一套前端项目结构是一件让人头疼的事情&#xff0c;就要重新复制一个上一个项目的前端框架和组件代码库。其中很多功能的模块组件都要重复拷贝&#xff0c;可以统一将…

如何使用ATS提高应用的安全性

App Transport Security&#xff0c;简短的说就是ATS&#xff0c;是iOS9和OS X El Capitan的一个新特性。App Transport Security 的目标是提高Apple 操作系统的安全性以及在此操作系统上运行的任何应用的安全性。 基于HTTP传输数据的网络请求都是明文。开启App Transport Secu…

手机客户端测试考虑的点

手机客户端测试考虑点总结 版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 此文未本人工作中的总结&#xff0c;特此总结。 异常场景&#xff1a; 网络异常&#xff0c;服务器异常&#xff0c;接口异常或参考参数篡改&#xff0c;断电&#xff0c;…