类和对象进一步了解c++

初始化列表

虽然构造函数能帮助我们完成初始化,但其实也就是构造函数赋值而已,根本不算真正的初始化。

所以,祖师爷就提出了一个初始化列表,用来初始化成员变量。

注意

每个成员变量在初始化列表中最多出现一次(初始化只能初始化一次)

你可以再初始化列表里不初始化成员变量,但是不可以初始化两次,最多出现一次

如下图,这是不被允许的

类中包含以下成员,必须放在初始化列表位置进行初始化:

  • 引用成员变量
  • const成员变量
  • 自定义类型成员(且该类没有默认构造函数时)

上面三个成员都有一个特点就是再创建的时候必须被初始化,这是c++规定的。对于引用和const我们清楚,const修饰的变量具有常性,必须再定义的时候初始化,引用也必须初始化,他不可以给空指针。但是自定义类型呢?对于自定义类型是看情况的,如果你的自定义类型没有默认构造函数,那我们就无法自动调用构造函数。那怎么办呢?根据定义又必须要初始化。所以,初始化列表接很好的解决了问题。初始化列表就是专门用来初始化成员变量的地方。

这里注意,初始化列表位置在构造函数上紧紧相连,他是构造函数的一部分,这是语法上的结构绑定。必须先使用初始化列表,才能执行构造函数。所以,对于一般的内置类型你可以直接就在初始化列表解决就行了。

但是这里有一个坑,初始化列表的执行顺序是和成员变量申明的顺序一样的。所以,建议初始化列表里的语句顺序和申明顺序一样。否则可能会出错。

大家看一下这段代码有问题吗?

答案是有问题的,由于执行顺序,_a会被先执行,但是_capacity又没有初始话值是随机的,这时开辟出来的空间你能确定吗?就会有一个内存泄漏的问题。而且是不会报错的,只会运行崩溃,这是很难受的。

那这时候大家可能就会有一个问题,那我们还要构造函数干什么呢?既然都可以靠初始化列表解决。答案是构造函数肯定是有用的。虽然在大部分的时候都会直接用初始化列表,但是我们在有些情况还是会用到构造函数的。

比如,你要动态开辟你一个二维数组,如果没有构造函数,你如何遍历循环呢?你又如何检查开辟是否成功呢?

这里不要非此即彼,在编程中其实没有那么多对立想法?大多时候都是基于实际情况的,要灵活运用。

对于初始化列表和构造函数的关系,大家要记住,一定是先执行初始化列表,再执行构造函数。如果你在初始话列表里没有显式初始化一个内置类型成员变量,那么初始化列表是不会对这个成员变量初始化的。值是随机的。

隐式类型转换

这个词大家因该不陌生,对于c语言来说是个运用很广的词。尤其是在int转换成double的时候。但这是属于内置类型的转换。c++提供了对于自定义类型的转化。

看以下这段代码,第一个是构造函数没问题。那第二个呢?这是什么,其实这里发生了隐式类型转换,int通过临时变量转换成一个自定义类型。如果这个大家看得陌生。那大家看看下面的这段代码

相信对于学过一点c++和java的人来说,肯定很是熟悉。但是知道为什么要这样写吗?string是c++的一个类,既然是类为什么可以直接赋值一个const char*呢?这就是隐式类型转换,但是大家要注意这里从语法看是先调用构造函数再调用构造拷贝函数。但是对于编译器看,连续调用两次编译器,会直接优化,直接调用一次构造函数,基于效率考虑。

explicit

那有什么办法可以取消掉这种隐式类型转换,答案就是在构造函数的前面加上一个explicit关键字,就可以取消掉

Static成员

我们把用static修饰的成员变量叫静态成员变量,static修饰的成员函数叫静态成员函数。

注意:静态成员函数是没有this指针的。静态不可以调用非静态的,只可以调用静态的。非静态的可以调用分静态的和静态的。这里主要是this指针的一个问题。由于,静态成员函数是没有this指针的,那你如果想要在静态函数里调用非静态函数,是需要传参this指针的。没有怎么传。所以,就不能调用非静态。但是对于非静态函数就没有这个烦恼。

这里主要是一个内存的问题。由于静态变量存储在在静态区,他不会随着对象的生命周期,而是在程序结束的时候,销毁。所以,静态变量不是属于对象,而是属于类。你可以把它理解为,静态变量是一个中央空调,谁都可以用。但是它不属于每一个人,而是属于公共的。由于他是属于公共的,所以他也不能在类里面使用构造函数和初始化列表,注意缺省值也是不能给的。因为缺省值是由初始化列表使用的。那真的不能给缺省值吗?其实加一个const修饰就可以了。但这里是为什么呢。大家可以先不用管这个,这个涉及到更复杂的语法。(这个不是祖师爷搞的,是组委会设计的)

那如何给静态变量定义呢,答案就是在全局变量赋值。既然是在全局变量赋值,那为什不用全局变量呢?所以,这里要加上私有权限符,这里还会有疑问?既然都是私有了?还怎么访问呢?答案就是,在全局定义,这个是规定。

  • 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区
  •  静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明
  • 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问
  •  静态成员函数没有隐藏的this指针,不能访问任何非静态成员
  •  静态成员也是类的成员,受public、protected、private 访问限定符的限制

下面是一个经典的static使用案例

只能在把类定义在堆上 或者 栈上

这里就很好的运用了static修饰的成员函数了

友元

友元函数

由于封装的性质,导致我们不能直接使用类里面的成员。但有些时候我们又要直接使用这些成员。所以,友元就诞生了。把一个普通函数,在类里面声明成友元函数就可以直接使用类里的成员,不受访问限定符的限制。

声明格式:在声明函数的前面加上一个friend关键字。注意,友元函数的声明只是一个普通的函数声明,他不是类的成员,不受访问限定符的影响。你可以把它放在任何位置,只要你喜欢。

比较经典的使用案例就是 流提取和流插入的运算符重载

这里是因为这两个运算符的重载,第一个参数必须是istream或者ostream,因此我们不能把他定义在类里面。但是又要使用类里面的私有成员,所以这里用友元函数就可以很好的解决这个问题。但是,由于友元破坏了封装。我们也不是很建议使用友元函数。可以在类里面定义一个get函数,返回私有成员。隔壁java就很喜欢这个用法。

友元类

和友元函数一样,都是定义在全局,在类里面声明成友元。同理,友元类也是不受访问限定符的影响。但是我们也讲过,这种做法破环了封装。所以,友元其实也不是很受欢迎。因此,大家了解一下就行了。

注意

友元是单向的,不是双向的。大家可以理解为,我把你当朋友,但是你可未必把我当成你的朋友。

内部类

  • 把一个类定义在一个类的里面,而不是定义在全局,我们管这个类叫内部类。
  • 内部类不属于它的外部类,不算外部类的成员,是外部类的友元函数。
  • 内部类受外部类访问限定符的影响。要想实例化内部类,必须先通过外部类的类域和限定符的指定

内部类的使用在c++其实很少,c++不太喜欢使用内部类。隔壁的java很喜欢用。

匿名对象

这里和匿名结构体可不一样。大家不要搞混概念。c++允许你在实例化对象的时候,不指定对象命。直接使用域名,注意这里虽然可以不用写对象名。但是需要加一个(),由于这里是匿名对象,它的使用和正常对象是一样的,都是使用.操作符。为了区分,需要加一个括号。要不然你一个类名直接使用.操作符访问成员。这是什么鬼,没有这种用法。

匿名对象的生命周期仅局限在它哪一行代码。但是如果是const引用,可以延长他的生命周期。这里是灵活运用的。匿名对象的产生就是为了即用即销毁。但是如果你是需要多次使用,那我就给你延长生命周期。这里是根据使用需求看的。大家可以想想祖师爷这个设计逻辑有问题吗?其实祖师爷在设计这些东西的时候,是考虑了很多的。我们要长远的看待这些东西。肯定是有他的用法的。

比如这里的隐式转换,如果你刚看觉得好想用处不是很大,但是你现在看看这段代码呢?就是因为隐式转换,我们可以直接使用函数输出对象,根本不需要再创建对象,然后初始化。

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

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

相关文章

rust学习笔记9-结构体与206.反转链表

结构体 rust不是面向对象语言,没有类(class),主要采用结构体(struct)来处理结构化数据,这点与go语言相似。 基本使用 struct Person {name: String,age: u32,height: f64, }fn main() {let p…

DDD该怎么去落地实现(4)多对多关系

多对多关系的设计实现 如题,DDD该如何落地呢?前面我通过三期的内容,讲解了DDD落地的关键在于“关系”,也就是通过前面我们对业务的理解先形成领域模型,然后将领域模型的原貌,形成程序代码中的服务、实体、…

论文阅读:CAN GENERATIVE LARGE LANGUAGE MODELS PERFORM ASR ERROR CORRECTION?

CAN GENERATIVE LARGE LANGUAGE MODELS PERFORM ASR ERROR CORRECTION? 生成式大语言模型能否进行自动语音识别(ASR)纠错? https://arxiv.org/pdf/2307.04172 文章目录 速览常规总结通俗版 摘要(Abstract)2. 引言&a…

python面向对象

目录 初识对象 类的成员方法 类和对象 构造方法 魔术方法 __str__ __lt__ __le__ __eq__ 封装 私有成员 继承 单继承 多继承 pass 复写 类型注解 1 变量的类型注解 方法1 使用: 方法2 注释 应用场景 2 函数(方法)的类型注解 3 混合类型注解 多态 初识对象 #设计…

C++的类型转换

C语言中的类型转换 在C语言中,如果赋值运算符左右两侧类型不同,或者形参与实参类型不匹配,或者返回值类型与 接收返回值类型不一致时,就需要发生类型转化,C语言中总共有两种形式的类型转换:隐式类型 转换和…

计算机网络-实验3拓扑结构

三、实验拓扑结构、实验步骤及结果分析 1. 实验拓扑结构 2. 实验步骤 3. 结果分析

[ISP] AE 自动曝光

相机通过不同曝光参数(档位快门时间 x 感光度 x 光圈大小)控制进光量来完成恰当的曝光。 自动曝光流程大概分为三部分: 1. 测光:点测光、中心测光、全局测光等;通过调整曝光档位使sensor曝光在合理的阈值内&#xff0…

聊一聊 IM 如何优化架构?

IM 系列 im doc 实时通讯文档仓库 聊一聊 IM 是什么? IM 即时通讯系统概览 聊一聊 IM 要如何设计? 聊一聊 IM 要如何设计功能模块? 聊一聊 IM 要如何进行架构设计? 聊一聊 IM 要如何进行技术选型? 聊一聊 IM 要…

开启mysql的binlog日志

mysql版本5.7 1.查看是否开启bin_log show global variables like’log_bin’; off的话需要先开启 在mysql的文件夹目录中找到my.ini 加一行log-bin“C:/ProgramData/MySQL/MySQL Server 5.7/logs/log-bin” 并提前创建好目录 2.数据库会把日志放进logs目录中 3.查看log日…

OpenHarmony4.1-轻量与小型系统ubuntu开发环境

因OpenHarmony官网提供包含轻量、小型与标准系统的全量代码非常宠大,解包后大概需要70G以上硬盘空间,如要编译标准系统则需要140G以上空间。 如硬盘空间有限与只使用轻量/小型OpenHarmony系统,则可以下载并直接使用本人裁剪源码过的ubuntu硬盘…

图论题目。

图论题目 检测环(dfsbfs)课程表 拓扑排序(dfsbfs)课程表2 二分图(dfs,bfs)判断二分图可能的二分法 Kruskal算法和Prim算法连接所有点的最小费用 Dijkstra算法概率最大的路径网络延时时间 检测环(dfsbfs) 课程表 题目 dfs: clas…

2025春新生培训数据结构(树,图)

教学目标: 1,清楚什么是树和图,了解基本概念,并且理解其应用场景 2,掌握一种建图(树)方法 3,掌握图的dfs和树的前中后序遍历 例题与习题 2025NENU新生培训(树&#…

如何防止Python网络爬虫爬取网站内容

要防止Python网络爬虫爬取网站内容,可以从以下几个方面入手: 遵守Robots.txt文件:首先,网站管理员可以通过robots.txt文件明确告知爬虫哪些页面可以抓取,哪些不可以。爬虫在抓取之前应先检查该文件,尊重网站…

Java数据结构第十六期:走进二叉树的奇妙世界(五)

专栏:Java数据结构秘籍 个人主页:手握风云 目录 一、非递归实现遍历二叉树 1.1. 二叉树的前序遍历 1.2. 二叉树的中序遍历 1.3. 二叉树的后序遍历 一、非递归实现遍历二叉树 1.1. 二叉树的前序遍历 我们这里要使用栈来进行实现。我们反向思考一下为…

yolov8_pose模型,使用rknn在安卓RK3568上使用

最近在使用rknn的一些功能,看了看文档以及自己做的一些jni,使用上yolov8_pose的模型. 1.我们先下载一下rknn的模型功能代码,rk有自己做的一套demo 地址:GitHub - airockchip/rknn_model_zooContribute to airockchip/rknn_model_zoo development by creating an account on G…

大模型推理时的尺度扩展定律

大模型推理时的尺度扩展定律 FesianXu at 20250212 at Wechat Search Team 前言 大模型的尺度扩展定律告诉我们:『LLM的性能会随着模型的参数量、模型的训练量、模型的训练数据量的增加而增加』。训练存在尺度扩展定律,测试也存在尺度扩展定律&#xff…

ubuntu防火墙iptables

文章目录 步骤开启自启防火墙iptables规则链Chains的区别 在 Ubuntu 上使用 iptables 配置防火墙并保证服务可用 步骤 #防火墙状态 systemctl status iptables systemctl start iptables #开启防火墙并且开启22端口 systemctl start iptables && iptables -A INPUT -p…

聊一聊 IM 如何优化监控

IM 系列 im doc 实时通讯文档仓库 聊一聊 IM 是什么? IM 即时通讯系统概览 聊一聊 IM 要如何设计? 聊一聊 IM 要如何设计功能模块? 聊一聊 IM 要如何进行架构设计? 聊一聊 IM 要如何进行技术选型? 聊一聊 IM 要…

[Windows] 批量为视频或者音频生成字幕 video subtitle master 1.5.2

Video Subtitle Master 1.5.2 介绍 Video Subtitle Master 1.5.2 是一款功能强大的客户端工具,能够批量为视频或音频生成字幕,还支持批量将字幕翻译成其他语言。该工具具有跨平台性,无论是 mac 系统还是 windows 系统都能使用。 参考原文&a…

探索紧急灾难处理的智慧:基于Neo4j的知识图谱问答系统

探索紧急灾难处理的智慧:基于Neo4j的知识图谱问答系统 在灾难突发的瞬间,时间就是生命!我们为您带来了一款基于Neo4j的紧急灾难突发处理知识图谱问答系统,助您快速获取至关重要的信息,提升应急响应效率! …