C++多态的使用

1. 多态

多种形态或多种实现方法,C++中的多态是指一种接口(指的是父类接口),多种实现方法(指的是每个子类所实现的方法),即通过父类接口实现调用子类的多种方法

1.1 构成多态性的条件:

1)具有继承关系的两个类

2)父类指针或引用指向子类

3)多种实现方法需要声明为虚函数

1.2 静态绑定

静态绑定(Static Binding),也称为早期绑定(Early Binding)或编译时绑定(Compile-time Binding),是指在程序的编译阶段确定方法、函数或操作的调用目标。在静态绑定中,编译器能够准确地确定调用哪个函数,因为调用关系在编译时已经被决定了。

静态绑定的优势在于效率高,因为编译器在编译时就能够确定调用关系,不需要在运行时进行查找。然而,静态绑定的缺点是缺乏灵活性,因为调用的目标在编译时就已经固定,无法根据运行时的条件进行动态调整。

与之相对的是动态绑定(Dynamic Binding),它是在运行时根据对象的实际类型来确定调用的方法。动态绑定通常与虚函数(virtual function)相关联,使得在运行时能够调用到对象实际类型的方法。

静态绑定(静态联编)

是指函数或表达式的地址,编译时就已经确定

根据对象的类型确定成员的调用地址

普通函数调用: 对于全局函数或类的静态成员函数,编译器在编译时就能够确定调用的函数。

void myFunction() {// some code
}int main() {myFunction(); // 静态绑定return 0;
}

非虚函数调用: 对于非虚函数,编译器也能够在编译时确定调用的函数。

class Base {
public:void nonVirtualFunction() {// some code}
};int main() {Base obj;obj.nonVirtualFunction(); // 静态绑定return 0;
}

1.3 动态绑定

动态绑定(动态联编)

是指函数或表达式的地址,运行时才确定

例子:

多态

根据指向的地址的对象的类型来确定成员的调用地址

C++中的多态性(polymorphism)通过虚函数(virtual functions)和动态绑定(dynamic binding)来实现。多态性允许在运行时根据对象的实际类型调用相应的函数,而不是根据变量或指针的静态类型。

在C++中,要实现多态性,你需要使用虚函数。虚函数是在基类中声明并在派生类中重写的函数。在基类中,你使用virtual关键字声明这个函数

duotai2.cpp

#include <iostream>
using namespace std;//多态的动态绑定
class Shape {
public:// 基类中的虚函数//virtual void draw() = 0;virtual void draw(){cout << "父类画一个形状" << endl;}
};class Circle : public Shape {
public:// 派生类中重写基类的虚函数void draw(){cout << "子类1画圆" << endl;}
};class Square : public Shape {
public:// 派生类中重写基类的虚函数void draw(){cout << "子类2画方" << endl;}
};int main() {Circle circle;Square square;// 使用基类指针指向派生类对象Shape* shapePtr = &circle;shapePtr->draw(); // 动态绑定,将调用 Circle 类的 draw 函数Shape* shapePtr2 = &square;shapePtr2->draw(); // 动态绑定,将调用 Square 类的 draw 函数return 0;
}

2. 虚析构函数

为什么要提出虚析构函数?解决资源(子类)得不到释放的问题

析构函数用vritual关键字来进行修饰

前提:

父类的指针或引用指向子类时

格式:virtual   ~类名(){}
例如:virtual  ~People()//虚析构函数{}	

2.1 面试题:

如果父类的析构函数不是虚函数,会带来(引起) 什么问题?

问题演示

xvgou.cpp
//虚析构函数
class People {
public:~People() { cout << "父类的虚构函数" << endl;}
};//class People {
//public:
//	virtual ~People() { //把父类声明为虚析构函数
//		cout << "父类的虚构函数" << endl;
//	}
//};class Son :public People{
public:~Son() {cout << "子类的虚构函数" << endl;}
};int main()
{//写法一,因为在堆上开辟的son,所以需要手动delete释放People* people = new Son;delete people;//写法二,因为在栈上开辟的son,不需要手动释放,程序会自动释放/*Son son;People* people = &son;*/return 0;
}

可以看到子类并未释放

带来的问题:资源(子类)得不到释放的问题

如果基类的析构函数不是虚函数,而你通过基类指针删除派生类对象,将只会调用基类的析构函数,而不是派生类的析构函数,这可能导致资源泄漏。

解决:将父类的析构函数声明为虚析构函数

xvgou.cpp
//虚析构函数
//class People {
//public:
//	~People() { 
//		cout << "父类的虚构函数" << endl;
//	}
//};class People {
public:virtual ~People() { //把父类声明为虚析构函数cout << "父类的虚构函数" << endl;}
};class Son :public People{
public:~Son() {cout << "子类的虚构函数" << endl;}
};int main()
{//写法一,因为在堆上开辟的son,所以需要手动delete释放People* people = new Son;delete people;//写法二,因为在栈上开辟的son,不需要手动释放,程序会自动释放/*Son son;People* people = &son;*/return 0;
}

3. 限制构造函数

限制对象的生成(创建)

将构造函数放置在protected或private修饰符下,用于限制对象的生成

3.1 举例

xvgou.cpp

//限制构造函数(将类的构造函数放在private下,限制类的实例化)
class Person {private:Person() {cout << "person的构造函数" << endl;}
};int main()
{//Person person;return 0;
}

3.2 当限制构造函数时,通过友元构造对象可行?

可以

xvgou.cpp

//限制构造函数(将类的构造函数放在private下,限制类的实例化)
class Person {
public:friend void create();//声明友元函数
private:Person() {cout << "person的构造函数" << endl;}
};//设置友元函数,看看可不可以实例化对象
void create() {Person person;
}int main()
{//Person person;//通过友元实例化对象create();return 0;
}

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

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

相关文章

【代数学作业1完整版-python实现GNFS一般数域筛】构造特定的整系数不可约多项式:涉及素数、模运算和优化问题

代数学作业1-完整版&#xff1a;python实现GNFS一般数域筛 写在最前面背景在GNFS算法中选择互质多项式时&#xff0c;需要考虑哪些关键因素&#xff0c;它们对算法的整体运行时间有何影响? 练习1题目题目分析Kleinjung方法简介通用数域筛法&#xff08;GNFS&#xff09;中的多…

浅谈开关量信号隔离器在钢铁厂除鳞系统的应用-安科瑞 蒋静

摘要&#xff1a;在钢铁生产线中&#xff0c;轧制是其中一项重要的加工工艺。通过轧制将金属坯料进行延展和定型&#xff0c;满足不同行业的使用要求。在轧制前需要进行除鳞&#xff0c;除鳞系统是通过高压水形成扇形水束&#xff0c;喷射到钢坯表面将氧化铁层剥离。高压水由高…

idea中java maven程序打JAR包的方式

JAR包是一种文件格式&#xff0c;用于将Java类、资源和元数据打包到一个文件中。它通常用于将Java库、应用程序或模块分发给其他开发人员或部署到不同的环境中。JAR包可以包含许多不同类型的文件&#xff0c;包括.class文件&#xff08;编译后的Java类&#xff09;、.java文件&…

Axure软件大全:原型设计下载与学习指南!

Axure可以有效地创建原型&#xff0c;包括绘制APP和网页的原型图、框架图、结构图等。Axure内置的小部件可以用来构建动态交互。即使新手设计师不懂程序代码&#xff0c;也可以在Axure中创建复杂、动态、功能丰富的原型。对于想要深入研究和花时间学习程序的设计师来说&#xf…

王力机器人安全门|用细节开拓高端精致家居生活

细微之处见风范,毫厘之优定乾坤。在追求高端品质的道路上,细节往往是最有力的诠释。如在入户门的选择方面,考虑到老人、孩子、宠物等每一位家庭成员不同需求的设计、科技运用才称得上是充满人性化、品质化的高端细节,幸福感直抵心灵。在该方面,王力机器人安全门做出了表率,每一…

【软件工程】设计概念

&#x1f34e;个人博客&#xff1a;个人主页 &#x1f3c6;个人专栏&#xff1a; 软件工程 ⛳️ 功不唐捐&#xff0c;玉汝于成 目录 前言 正文 软件工程中的设计概念 概念&#xff1a; 结语 我的其他博客 前言 在数字时代的浪潮中&#xff0c;软件工程设计成为塑造创新…

【大数据Hive】hive 运算符使用详解

目录 一、前言 二、hive 运算符分类 三、hive 运算符操作演示 3.1 数据准备 创建表dual 加载一个文件dual.txt到dual表中 模拟测试 3.2 关系运算符 is null空值判断 is not null 非空值判断 like使用 3.3 算术运算符 取整操作 取余操作: % 位与操作: & …

Java 19的未来:新特性、性能优化和更多

目录 前言 新特性的引入 1. 模式匹配的扩展 2. 增强的模式匹配异常处理 3. 基于记录的反射 4. 引入静态方法的接口 性能优化 1. 垃圾收集器的改进 2. 即时编译器的增强 3. 并行处理的改进 Java编程的前景展望 1. 更多的应用场景 2. 更强的生态系统 3.…

Hive/SparkSQL中UDF/UDTF/UDAF的含义、区别、有哪些函数

Hive官网&#xff1a;https://cwiki.apache.org/confluence/display/Hive/LanguageManualUDF#LanguageManualUDF-Built-inTable-GeneratingFunctions(UDTF) 1.UDF(User-Defined Function) 含义 即用户定义函数&#xff0c;UDF用于处理一行数据并返回一个标量值(单个值)&#x…

【OpenCV】OpenCV:计算机视觉的强大工具库

摘要   OpenCV是一个广泛应用于计算机视觉领域的开源工具库&#xff0c;为开发者提供了丰富的图像处理和计算机视觉算法。本文将介绍OpenCV的功能和应用领域&#xff0c;并探讨它在实践中的重要性和前景。 计算机视觉的强大工具库 一、什么是OpenCV&#xff1f;二、OpenCV的功…

c# 捕获全部线程的异常 试验

1.概要 捕获全部线程的异常 试验&#xff0c;最终结果task的异常没有找到捕获方法 2.代码 2.1.试验1 2.1.1 试验结果 2.2 代码 2.2.1主程序代码 using NLog; using System; using System.Threading; using System.Windows.Forms;namespace 异常监控 {static class Program…

CCNP课程实验-03-Route_Path_Control_CFG

目录 实验条件网络拓朴需求 基础配置需求实现1.A---F所有区用Loopback模拟&#xff0c;地址格式为&#xff1a;XX.XX.XX.XX/32&#xff0c;其中X为路由器编号。根据拓扑宣告进对应协议。A1和A2区为特例&#xff0c;A1&#xff1a;55.55.55.0/24&#xff0c;A2&#xff1a;55.55…

RDS创建数据库

目录 创建数据库 创建账号与授权 连接RDS数据库 创建数据库 在创建数据库的页面&#xff0c;你需要设置数据库的名称、字符集、排序规则等信息。 字符集&#xff1a;字符集&#xff08;Character set&#xff09;是多个字符的集合&#xff0c;字符集种类较多&#xff0c;每个…

typescript,eslint,prettier的引入

typescript 首先用npm安装typescript&#xff0c;cnpm i typescript 然后再tsc --init生成tsconfig.json配置文件&#xff0c;这个文件在package.json同级目录下 最后在tsconfig.json添加includes配置项&#xff0c;在该配置项中的目录下&#xff0c;所有的d.ts中的类型可以在…

惠普打印机---共享打印机安装 --连接

1. 远程连接 输入 winR ,再输入共享打印机的连接的IP 2.进入 连接 界面 3.右击打印机 &#xff0c;点击连接 &#xff0c;就可以添加打印机设备 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/ba03aea8156642d58982fd2ce0934b45.png 方法二、 添加打印机 2.…

什么是边缘计算:最全指南

什么是边缘计算 边缘计算是一个流行语&#xff0c;如云、物联网和人工智能。简单地说&#xff0c;边缘计算带来了网络的去中心化。边缘计算是即将到来的技术增强和进步。“边缘”一词的字面含义是地球上以分布式方式提供服务的地理位置。 边缘计算是一种分布式计算系统&#…

网络安全法解读之思维导图

一、出台背景 二、法律基础 三、网络安全法架构 1、第一章 总则&#xff08;1-14条&#xff09; 2、第二章 网络安全支持与促进&#xff08;15-20条&#xff09; 3、 第三章 网络运行安全&#xff08;21-39条&#xff09; &#xff08;1&#xff09;第一节 一般规定 &#xf…

leaflet学习笔记-leaflet-ajax获取数据(五)

前言 地图开发中都会用一些GeoJSON数据进行渲染&#xff0c;这是用就会需要加载GeoJSON数据&#xff0c;这时就可以使用leaflet-ajax进行数据的获取 数据准备 本文通过阿里云的地图选择器&#xff08;DataV.GeoAtlas官网&#xff09;可以找到云南省的GeoJSON数据&#xff0c…

【C++杂货铺】C++11新特性——可变参数模板

文章目录 一、可变模板参数相关概念的引入二、获取参数包中参数的个数三、递归函数方式展开参数包四、逗号表达式展开参数包五、可变模板参数的实际应用——emplace相关接口5.1 回顾一下 push_back 的三种用法5.2 emplace_back 使用方法介绍5.3 听说 emplace_back 可以提高效率…

MAC电脑安装java开发工具

一、安装brew 1.1、官网地址 链接 1.2、更新地址 二、安装 java brew install openjdk11 三、安装gradle Gradle安装与配置教程 - 知乎 四、GIT 4.1、GIT安装 brew install git 4.2、rsa ssh-keygen -t rsa -C "jhestarbucks.com" 五、自动搭建一个springBoot…