【C++语言】类和对象(下)
一、再谈构造函数
1.1 构造函数体赋值
在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。
class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};
虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称之为对对象中成员变量的初始化,构造函数体中的语句只能称之为将其赋初值,而不能称为初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值。
1.2 初始化列表
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每一个“成员变量”后面跟着一个放在括号中的初始值或者表达式。
class Date
{
public:Date(int year, int month, int day): _year(year), _month(month), _day(day){}private:int _year;int _month;int _day;
};
注意:
- 每一个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)
- 类中包含以下成员,必须放在初始化列表位置进行初始化:
- 引用成员变量
- const 成员变量
- 自定义类型成员(且该类没有默认构造函数时)
- 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义成员变量,一定会先试用初始化列表初始化。
- 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。
1.3 explicit 关键字
构造函数不仅可以构造与初始化对象,对于接受单个参数的构造函数,还具有类型转换的作用。接收单个参数的构造函数具体表现:
- 构造函数只有一个参数
- 构造函数有多个参数,除第一个参数没有默认值,其余参数都有默认值
- 全缺省构造函数
class Date
{
public:// 1. 单参构造函数,没有使用explicit修饰,具有类型转换作用// explicit修饰构造函数,禁止类型转换---explicit去掉之后,代码可以通过编译explicit Date(int year):_year(year){}/*// 2. 虽然有多个参数,但是创建对象时后两个参数可以不传递,没有使用explicit修饰,具有类型转换作用// explicit修饰构造函数,禁止类型转换explicit Date(int year, int month = 1, int day = 1): _year(year), _month(month), _day(day){}*/Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}
private:int _year;int _month;int _day;
};void Test()
{Date d1(2022);// 用一个整形变量给日期类型对象赋值// 实际编译器背后会用2023构造一个无名对象,最后用无名对象给d1对象进行赋值d1 = 2023;// 将1屏蔽掉,2放开时则编译失败,因为explicit修饰构造函数,禁止了单参构造函数类型转换的作用
}
上述代码可读性不是很好,用 explicit 修饰构造函数,将会禁止构造函数的隐式转换。
二、static 成员
2.1 概念
声明为 static 的类成员成为类的静态成员,用 static 修饰的成员变量,称之为静态成员变量;用 static 修饰的成员函数,称之为静态成员函数,静态成员变量一定要在类外进行初始化。
2.2 特性
- 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区
- 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明
- 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问
- 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
- 静态成员也是类的成员,受public、protected、private 访问限定符的限制
【问题】
1. 静态成员函数可以调用非静态成员函数吗?不可以。
静态成员函数属于类,而非静态成员函数属于类的实例。静态成员函数在没有实例对象的情况下可以被调用,它不能访问实例的成员(包括非静态成员函数),因为静态成员函数没有
this
指针,也就无法访问实例的数据。非静态成员函数需要依赖具体的对象实例,而静态成员函数是独立于任何对象的。因此,静态成员函数无法直接调用非静态成员函数。
2. 非静态成员函数可以调用类的静态成员函数吗?可以。
非静态成员函数属于类的实例,可以通过
this
指针访问实例的成员,同时也可以访问类的静态成员。静态成员函数是属于类的,而不是某个特定的实例,所以非静态成员函数是可以访问和调用静态成员函数的。
三、友元
友元提供了一个突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。友元分为:友元函数和友元类。
3.1 友元函数
现在尝试去重载 operator<< ,然后发现没有方法将 operator<< 重载成成员函数。因为 cout 的输出流对象和隐含的 this 指针在抢占第一个参数的位置。this 指针默认是第一个参数也就是左操作数了。但是实际使用中 cout 需要是第一个形参对象,才能正常使用。所以要将 operator<< 重载成全局函数,但是有会导致类外没有办法访问成员,此时就需要友元来进行解决。
class Date
{
public:Date(int year, int month, int day): _year(year), _month(month), _day(day){}// d1 << cout; -> d1.operator<<(&d1, cout); 不符合常规调用// 因为成员函数第一个参数一定是隐藏的this,所以d1必须放在<<的左侧ostream& operator<<(ostream& _cout){_cout << _year << "-" << _month << "-" << _day << endl;return _cout;}
private:int _year;int _month;int _day;
};
友元函数可以直接访问类的私有成员,他是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加上 friend 关键字。
class Date
{friend ostream& operator<<(ostream& _cout, const Date& d);friend istream& operator>>(istream& _cin, Date& d);
public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}
private:int _year;int _month;int _day;
};ostream& operator<<(ostream& _cout, const Date& d)
{_cout << d._year << "-" << d._month << "-" << d._day;return _cout;
}istream& operator>>(istream& _cin, Date& d)
{_cin >> d._year;_cin >> d._month;_cin >> d._day;return _cin;
}int main()
{Date d;cin >> d;cout << d << endl;return 0;
}
注意:
- 友元函数可访问类的私有和保护成员,但不是类的成员函数
- 友元函数不能使用const修饰
- 友元函数可以在类定义的任何地方声明,不受访问限定符限制
- 一个函数可以是多个类的友元函数
- 友元函数的调用与普通函数的调用原理相同
3.2 友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
- 友元关系是单向的,不具有交换性。 比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time
- 类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。
- 友元关系不能传递,如果B是A的友元,C是B的友元,则不能说明C时A的友元。
- 友元关系不能继承
四、内部类
概念:如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,他不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。
注意: 内部类就是外部类的友元类 ,参见友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。
特性:
- 内部类可以定义在外部类的public、protected、private都是可以的。
- 注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。
- sizeof(外部类)=外部类,和内部类没有任何关系。
五、再次理解封装
- 用户先要对现实中洗衣机实体进行抽象---即在人为思想层面对洗衣机进行认识,洗衣机有什么属性,有那些功能,即对洗衣机进行抽象认知的一个过程
- 经过1之后,在人的头脑中已经对洗衣机有了一个清醒的认识,只不过此时计算机还不清楚,想要让计算机识别人想象中的洗衣机,就需要人通过某种面相对象的语言(比如:C++、Java、Python等)将洗衣机用类来进行描述,并输入到计算机中
- 经过2之后,在计算机中就有了一个洗衣机类,但是洗衣机类只是站在计算机的角度对洗衣机对象进行描述的,通过洗衣机类,可以实例化出一个个具体的洗衣机对象,此时计算机才能洗衣机是什么东西。
- 用户就可以借助计算机中洗衣机对象,来模拟现实中的洗衣机实体了。
相关文章:
【C++语言】类和对象(下)
一、再谈构造函数 1.1 构造函数体赋值 在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。 class Date { public:Date(int year, int month, int day){_year year;_month month;_day day;} private:int _year;int _mont…...

【Spring】什么是Spring?
什么是Spring? Spring是一个开源的轻量级框架,是为了简化企业级开发而设计的。我们通常讲的Spring一般指的是Spring Framework。Spring的核心是控制反转(IoC-Inversion of Control)和面向切面编程(AOP-Aspect-Oriented Programming)。这些功能使得开发者…...
全面理解-c++11中的智能指针
在 C 中,智能指针(Smart Pointers) 是用于自动管理动态分配内存的类模板,遵循 RAII(Resource Acquisition Is Initialization) 原则,确保资源在生命周期结束时被正确释放,避免内存泄…...

【jmeter】在windows中,创建的变量,在jmeter中,读取变量失败的问题,路径问题
1.0 在windows中,jmeter读取变量失败 在路径配置的时候,配置按照D:\FtpDownload\${file_name}运行之后,下载的文件,文件名出现问题 \取消了$符号的意义,所以需要更改路径 D:\\FtpDownload\\${file_name}...

【CubeMX-HAL库】STM32F407—无刷电机学习笔记
目录 简介: 学习资料: 跳转目录: 一、工程创建 二、板载LED 三、用户按键 四、蜂鸣器 1.完整IO控制代码 五、TFT彩屏驱动 六、ADC多通道 1.通道确认 2.CubeMX配置 ①开启对应的ADC通道 ②选择规则组通道 ③开启DMA ④开启ADC…...

使用 POI-TL 和 JFreeChart 动态生成 Word 报告
文章目录 前言一、需求背景二、方案分析三、 POI-TL JFreeChart 实现3.1 Maven 依赖3.3 word模板设置3.2 实现代码 踩坑 前言 在开发过程中,我们经常需要生成包含动态数据和图表的 Word 报告。本文将介绍如何结合 POI-TL 和 JFreeChart,实现动态生成 W…...

xxl-job的分片广播
目录 xxl-job的分片广播 场景引入 xxl-job简介 xxl-job的部署安装 代码编写 1.导入依赖 2.yml文件编写 3.编写xxl-job执行器配置类,维护一个xxl-job执行器的bean 4.编写第一个任务,任务名字叫firstJob 5.进入服务端,增加执行器和任务…...

MobaXterm破解会话上限限制
1. 下载安装包MobaXterm-Keygen 下载路径: https://gitcode.com/gh_mirrors/mob/MobaXterm-Keygen 2. 搭建python3环境 window下python3环境搭建可参考网站: https://blog.csdn.net/enteracity/article/details/135479689 3. 生成文件Custom.mxtpro…...
vscode设置保存时自动缩进和格式化
参考博客 如何在 VSCode 中自动缩进你的代码 | Linux 中国 省流 使用 Ctrl Shift P 来打开命令模式,搜索 Open User Settings 并按下回车你需要搜索 Auto Indent,并在 “编辑器:自动缩进(Editor: Auto Indent)” 中选择 “全部(Full)”P…...

一键查看电脑各硬件详细信息 轻松查看电脑硬件参数
今天为大家推荐两款非常实用的电脑硬件查看软件,它们能够一键快速查看电脑的各种配置信息,使用起来非常方便。 一键查看电脑各硬件详细信息 这款软件是绿色版的,无需安装,打开即可使用,文件大小仅为900多KB࿰…...

【C++11】lambda和包装器
1.新的类功能 1.1默认的移动构造和移动赋值 原来C类中,有6个默认成员函数:构造函数/析构函数/拷⻉构造函数/拷⻉赋值重载/取地址重 载/const 取地址重载,最后重要的是前4个,后两个⽤处不⼤,默认成员函数就是我们不写…...

react redux用法学习
参考资料: https://www.bilibili.com/video/BV1ZB4y1Z7o8 https://cn.redux.js.org/tutorials/essentials/part-5-async-logic AI工具:deepseek,通义灵码 安装相关依赖: 使用redux的中间件: npm i react-reduxreact-…...
前端HTML标签 meta中常见的一些属性
meta中常见的一些属性 <meta/> 标签的属性 <meta/> 是什么? <meta/> 标签主要用于表示和当前文档相关的 元数据 信息。 而 元数据(metadata),简单的来说就是描述数据的数据。例如,一个 HTML 文件是一…...

127,【3】 buuctf [NPUCTF2020]ReadlezPHP
进入靶场 吓我一跳 查看源码 点击 审计 <?php// 定义一个名为 HelloPhp 的类,该类可能用于执行与日期格式化相关的操作 class HelloPhp {// 定义一个公共属性 $a,用于存储日期格式化的模板public $a;// 定义一个公共属性 $b,用于存储…...
继承(python)
一、基础知识 (一)定义:子类能继承父类所有的公有属性和公有方法(先使用子类的方法、属性) (二)格式: class 子类名(父类名): #父类 class Ph…...
驱动开发系列36 - Linux Graphics 2D 绘制流程
一: 概述 在Linux中,2D绘制流程是操作系统、图形库、显示协议、驱动程序等多个组件协调工作的结果。整体流程如下步骤所示: 1. 客户端请求:客户端程序(如GTK、Qt应用程序)通过X11协议与Xorg-Server通信(或通过Wayland协议与Wayland合成器通信)、请求绘制2D图形,比如绘制…...
STL函数算法笔记
STL函数算法笔记 今天我们来学习的是STL库中的一些函数。首先,STL这个东西大家一定非常熟悉,里面很多的数据结构都帮了大家不少忙,那么今天我们就来说几个重要的数据结构。 向量 向量,也就是数据结构vector,你也可以称之为动态数组,本质跟数组差不多,只不过有一些好处…...

【Vue】在Vue3中使用Echarts的示例 两种方法
文章目录 方法一template渲染部分js部分方法一实现效果 方法二template部分js or ts部分方法二实现效果 贴个地址~ Apache ECharts官网地址 Apache ECharts示例地址 官网有的时候示例显示不出来,属于正常现象,多进几次就行 开始使用前,记得先…...
小红书自动化:如何利用Make批量生成爆款笔记
小红书自动化:如何利用Make制作个人自媒体中心,批量生成爆款笔记 引言 在如今信息爆炸的时代,如何高效地获取和分享优质内容,成为了每位自媒体工作者必须面对的挑战。你是否想过,如果能够将这项繁复的工作实现自动化…...

学习率调整策略 | PyTorch 深度学习实战
前一篇文章,深度学习里面的而优化函数 Adam,SGD,动量法,AdaGrad 等 | PyTorch 深度学习实战 本系列文章 GitHub Repo: https://github.com/hailiang-wang/pytorch-get-started 本篇文章内容来自于 强化学习必修课:引…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明
AI 领域的快速发展正在催生一个新时代,智能代理(agents)不再是孤立的个体,而是能够像一个数字团队一样协作。然而,当前 AI 生态系统的碎片化阻碍了这一愿景的实现,导致了“AI 巴别塔问题”——不同代理之间…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...

学习STC51单片机32(芯片为STC89C52RCRC)OLED显示屏2
每日一言 今天的每一份坚持,都是在为未来积攒底气。 案例:OLED显示一个A 这边观察到一个点,怎么雪花了就是都是乱七八糟的占满了屏幕。。 解释 : 如果代码里信号切换太快(比如 SDA 刚变,SCL 立刻变&#…...

GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...