C++程序设计-第六/七/八章 运算符重载/包含与继承/虚函数和多态性【期末复习|考研复习】

前言

总结整理不易,希望大家点赞收藏。

给大家整理了一下C++程序设计中的重点概念,以供大家期末复习和考研复习的时候使用。


C++程序设计系列文章传送门:
第一章 面向对象基础
第四/五章 函数和类和对象
第六/七/八章 运算符重载/包含与继承/虚函数和多态性
第九/十一/十二章 模板/输入/输出流/标准模板库


文章目录

  • 前言
  • 第六章 运算符重载
    • 6.1 何时需要定义赋值运算符
    • 6.2 举例说出你所了解的必须以类成员方式定义的运算符
    • 6.3 C++编译器为类自动产生的四个默认成员函数分别是什么
  • 第七章 包含与继承
    • 7.1 包含和继承是面向对象语言提供的两种重要的代码复用机制阐述它们有什么区别如何选择应用
    • 7.2 继承等级是什么?
    • 7.3 继承中的类的赋值兼容原则
  • 第八章 虚函数和多态性
    • 8.1 什么是虚函数?什么是纯虚函数?为什么引入虚函数和纯虚函数?
    • 8.2 析构函数应该是虚函数吗?为什么?
    • 8.3 为什么默认的析构函数不是虚函数?
  • 练手题
    • 9.1
    • 9.2
  • 下一章传送门


第六章 运算符重载

6.1 何时需要定义赋值运算符

如果一个类需要进行赋值操作,就需要定义赋值运算符。

class MyClass {
public:MyClass& operator=(const MyClass& other) { // 实现赋值操作的代码return *this;}
};

对于含有指针成员的类来说,使用默认的赋值运算符可能会导致指针的浅拷贝问题。在这种情况下,需要自定义赋值运算符,以确保指针的深拷贝,避免出现潜在的内存泄漏和错误。

6.2 举例说出你所了解的必须以类成员方式定义的运算符

赋值运算符(=)、下标运算符([])、函数调用运算符(())、成员访问运算符(->)。这些运算符必须被定义为成员函数的原因是它们需要访问类的私有成员,只有成员函数才能访问类的私有成员。另外,它们的左操作数都是类的对象,因此只有成员函数才能访问对象的成员。

6.3 C++编译器为类自动产生的四个默认成员函数分别是什么

默认成员函数包括默认构造函数、析构函数、拷贝构造函数和拷贝赋值运算符。

Mystring(const char* str=nullptr);			   
~Mystring();							   
Mystring(const Mystring& other);			   	// 要进行深拷贝
Mystring& operator=(const Mystring& other);  	//重载操作符

第七章 包含与继承

7.1 包含和继承是面向对象语言提供的两种重要的代码复用机制阐述它们有什么区别如何选择应用

包含是指在一个类中嵌入另一个类的对象,通过调用该对象的方法来实现功能复用。这种方式可以实现代码的模块化和灵活性,但需要手动管理对象的生命周期和内存分配。
继承是指一个类可以从另一个类继承属性和方法,从而实现代码的复用和扩展。这种方式可以减少代码的重复,提高代码的可维护性和可扩展性,但也可能导致代码的耦合度过高,难以维护和扩展。
在选择应用时,需要根据具体的需求和设计原则进行权衡。一般来说,如果需要实现简单的功能复用,可以选择包含;如果需要实现复杂的继承关系和代码复用,可以选择继承。

7.2 继承等级是什么?

公有继承(public inheritance):派生类可以访问基类的公有成员和保护成员,但不能访问基类的私有成员。
保护继承(protected inheritance):派生类可以访问基类的公有成员和保护成员,但不能访问基类的私有成员。
私有继承(private inheritance):派生类可以访问基类的公有成员和保护成员,但不能访问基类的私有成员。
虚拟继承(virtual inheritance):用于解决多重继承带来的问题,将同一基类的多个派生类共享同一个基类子对象,避免多次复制基类数据成员。防止菱形继承。class A; class B::virtual public A{}; class C::virtual public A{};
只要是父类中private成员无论以什么方式继承,儿子都无法访问;如果是公有继承儿子中的访问权限不变;如果是保护继承,儿子中父亲除了private成员其余均为protected成员;如果是私有继承,均为private成员。
子类不会继承父类的构造函数、析构函数和赋值操作符

7.3 继承中的类的赋值兼容原则

1、子类对象可以当作父类的对象使用(子类是特殊的父类)
2、子类对象可以直接赋值父类对象
3、子类对象可以直接初始化父类对象
4、父类指针可以直接指向子类对象
5、父类引用可以直接引用子类对象

第八章 虚函数和多态性

8.1 什么是虚函数?什么是纯虚函数?为什么引入虚函数和纯虚函数?

被 virtual 关键字修饰的成员函数称为虚函数。在虚函数后面添加 =0 ,虚函数就成为纯虚函数。纯虚函数只是一个接口,它的具体实现需要由子类来完成,子类必须实现纯虚函数,否则子类也会变成抽象类。
引入纯虚函数可以将基类的某些函数强制为虚函数,并且必须被子类实现。引入虚函数和纯虚函数的目的在于实现多态性。通过定义虚函数和纯虚函数,可以使得子类可以覆盖基类中的函数,从而实现子类对于函数的重写和扩展。而通过运行时动态绑定的方式,可以根据对象的实际类型来确定调用相应的函数,从而实现多态性。

8.2 析构函数应该是虚函数吗?为什么?

当一个类被继承时,如果其析构函数不是虚函数,那么在使用基类指针或引用指向派生类对象并删除这个对象时,可能会导致只有基类部分被析构,派生类部分的资源没有被正确地释放,从而导致内存泄漏或者其它的错误。这是因为在这种情况下,编译器只会调用基类的析构函数,而不会调用派生类的析构函数,因为指针或引用的静态类型是基类类型,因此需要使用虚析构函数来确保正确地释放资源。
总之,如果一个类可能会被继承,那么就应该将其析构函数声明为虚函数,以确保正确释放派生类的资源。

8.3 为什么默认的析构函数不是虚函数?

当类中有虚成员函数时,类会自动进行一些额外工作。这些额外的工作包括生成虚函数表和虚表指针,虚表指针指向虚函数表。每个类都有自己的虚函数表,虚函数表的作用就是保存本类中虚函数的地址,我们可以把虚函数表形象地看成一个数组,这个数组的每个元素存放的就是各个虚函数的地址。当我们创建一个类时,系统默认我们不会将该类作为基类,所以就将默认的析构函数定义成非虚函数,这样就不会占用额外的内存空间。同时,系统也相信程序开发者在定义一个基类时,会显示地将基类的析构函数定义成虚函数,此时该类才会维护虚函数表和虚表指针。

练手题

9.1

在这里插入图片描述
在这里插入图片描述

9.2

在这里插入图片描述

下一章传送门

第九/十一/十二章 模板/输入/输出流/标准模板库

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

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

相关文章

《探索虚拟与现实的边界:VR与AR谁更能引领未来?》

引言 在当今数字时代,虚拟现实(VR)和增强现实(AR)技术正以惊人的速度发展,并逐渐渗透到我们的日常生活中。它们正在重新定义人与技术、人与环境之间的关系,同时也为各行各业带来了全新的可能性。然而,究竟是VR还是AR更有潜力改变未来?本文将围绕这一问题展开深入探讨。…

Canal安装使用

一 Canal介绍 canal是阿里巴巴旗下的一款开源项目,纯Java开发。基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了MySQL(也支持mariaDB)。 背景 早期,阿里巴巴B2B公司因为存在杭州和美国…

少儿编程 蓝桥杯青少组科技素养题 信息素养真题及解析第25套

少儿编程 科技素养 信息素养真题第25套 1、旅行结束之后,回到家的小蓝决定将照片备份在云端的网盘上。备份照片主要占用的是小蓝家的( )带宽 A、下行 B、上行 C、文件 D、数据 答案:B 考点分析:主要考查网络相关知识,要将照…

公众号IP白名单已添加服务器IP 122.88... 依然给出 40164 错误

公众号的IP白名单已添加 122.88... 依然给出 40164 错误。 {"errcode":40164,"errmsg":"invalid ip 122.88... ipv6 ::ffff:122.88..., not in whitelist rid: 65e85a07-458dfc0d-16003e03"} 解决方案: 一、检查 AppID 是否正确&…

【数学】【组合数学】1830. 使字符串有序的最少操作次数

作者推荐 视频算法专题 本博文涉及知识点 数学 组合数学 LeetCode1830. 使字符串有序的最少操作次数 给你一个字符串 s &#xff08;下标从 0 开始&#xff09;。你需要对 s 执行以下操作直到它变为一个有序字符串&#xff1a; 找到 最大下标 i &#xff0c;使得 1 < i…

Javaweb之Maven高级之继承的详细解析

2.1 继承 我们可以再创建一个父工程 tlias-parent &#xff0c;然后让上述的三个模块 tlias-pojo、tlias-utils、tlias-web-management 都来继承这个父工程 。 然后再将各个模块中都共有的依赖&#xff0c;都提取到父工程 tlias-parent中进行配置&#xff0c;只要子工程继承了…

C++单例模式、工厂模式

一、单例模式 (一) 什么是单例模式 1. 是什么&#xff1f; 在系统的整个生命周期内&#xff0c;一个类只允许存在一个实例。 2. 为什么&#xff1f; 两个原因&#xff1a; 节省资源。方便控制&#xff0c;在操作公共资源的场景时&#xff0c;避免了多个对象引起的复杂操作…

云原生之容器编排实践-ruoyi-cloud项目部署到K8S:Nginx1.25.3

背景 前面搭建好了 Kubernetes 集群与私有镜像仓库&#xff0c;终于要进入服务编排的实践环节了。本系列拿 ruoyi-cloud 项目进行练手&#xff0c;按照 MySQL &#xff0c; Nacos &#xff0c; Redis &#xff0c; Nginx &#xff0c; Gateway &#xff0c; Auth &#xff0c;…

异步编程实战:使用C#实现FTP文件下载及超时控制

博客标题: 异步编程实战&#xff1a;使用C#实现FTP文件下载及超时控制 如果你的函数不是async&#xff0c;你仍然可以实现相同的超时功能&#xff0c;但你将不得不依赖更多的同步代码或使用.Result或.GetAwaiter().GetResult()来阻塞等待任务完成&#xff0c;这可能导致死锁的风…

mybatis-plus整合spring boot极速入门

使用mybatis-plus整合spring boot&#xff0c;接下来我来操作一番。 一&#xff0c;创建spring boot工程 勾选下面的选项 紧接着&#xff0c;还有springboot和依赖我们需要选。 这样我们就创建好了我们的spring boot&#xff0c;项目。 简化目录结构&#xff1a; 我们发现&a…

uniapp 解决请求出现 /sockjs-node/info?t=问题

1. uniapp请求出现 /sockjs-node/info?t问题 1.1. 问题 uniapp项目老是出现 http://192.168.2.106:8080/sockjs-node/info?t1709704280949 1.1. sockjs-node介绍 sockjs-node 是一个JavaScript库&#xff0c;提供跨浏览器JavaScript的API&#xff0c;创建了一个低延迟、全…

JAVA实战开源项目:快递管理系统(Vue+SpringBoot)

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、研究内容2.1 数据中心模块2.2 快递类型模块2.3 快递区域模块2.4 快递货架模块2.5 快递档案模块 三、界面展示3.1 登录注册3.2 快递类型3.3 快递区域3.4 快递货架3.5 快递档案3.6 系统基础模块 四、免责说明 一、摘要 1.1 项目介绍 …