当前位置: 首页 > news >正文

C++初阶学习第五弹——类与对象(下)

类与对象(上):C++初阶学习第三弹——类与对象(上)-CSDN博客

类和对象(中):C++初阶学习第四弹——类与对象(中)-CSDN博客

一.赋值运算符重载

1.1 运算符重载

C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其 返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。

函数名字为:关键字operator后面接需要重载的运算符符号。

函数原型:返回值类型 operator操作符(参数列表)

注意:

1.不能通过连接其他符号来创建新的操作符:比如operator@

2.重载操作符必须有一个类类型参数

3.用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不 能改变其含义作为类

4.成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this

5.   .* :: sizeof ?: . 注意以上5个运算符不能重载。这个经常在笔试选择题中出现。

1.2 赋值运算符重载

1. 赋值运算符重载格式 参数类型:const T&,传递引用可以提高传参效率

2.返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值

3.检测是否自己给自己赋值

4.返回*this :要复合连续赋值的含义

二.构造函数进阶 

2.1构造函数体赋值

在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。

class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};
int main()
{Date d1();return 0;
}

虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量 的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始 化一次,而构造函数体内可以多次赋值。

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;
};

不过要注意的是

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

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

引用成员变量

const成员变量 

自定义类型成员(且该类没有默认构造函数时)

class A
{
public:A(int a):_a(a){}
private:int _a;
};
class B
{
public:B(int a, int ref):_aobj(a), _ref(ref), _n(10){}
private:A _aobj; // 没有默认构造函数int& _ref; // 引用const int _n; // const 
};

 1.3 explicit关键字

对于接受单个参数的构造函数,构造函数不仅可以构造与初始化对象,还具有类型转换的作用。

1、构造函数只有一个参数

2、构造函数有多个参数,但是只有一个没有默认值

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修饰构造函数,禁止了单参构造函数类型转换的作
//	用
}


三.static成员

用static修饰的成员变量就是类中的静态成员变量,用static修饰的成员函数就是静态成员函数

我们需要注意的是静态成员变量一定要在类外进行初始化

class A
{
private:static int _a;
};//在类外对_a进行初始化
int A::_a = 0;int main()
{return 0;
}

1、静态成员存放在静态区,为所有类成员共享

2、静态成员必须在类外定义(初始化),类中只是声明

3、静态成员访问方式:类名::静态成员或者对象.静态成员

四.友元

1.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修饰

友元函数可以在类定义的任何地方声明,不受类访问限定符限制

一个函数可以是多个类的友元函数

友元函数的调用与普通函数的调用原理相同

1.2  友元类

友元类跟上面的友元函数很想,也是间接访问一个类中私有化成员的一种方法,友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

class Time
{friend class Date;     //声明Date为友元类
private:int _hour;int _min;
};
class Date
{
public:void test(int hour, int min){_t._hour = hour;       //可以在Date类中直接引用Time类私有成员变量_t._min = min;}
private:int _year;int _month;int _day;Time _t;
};

1.3 内部类

如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类, 它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越 的访问权限。

 总结:

1、内部类和外部类实际上还是两个完全独立的类,完全可以将它们两个分开写

2、内部类是外部类的友元类,可以访问外部类的私有成员,但外部类不是内部类的友元类

3、内部类可以直接访问外部类的静态成员,不需要外部类的对象名或者类名

class A
{
private:static int k;int h;
public:class B // B天生就是A的友元{public:void foo(const A& a){cout << k << endl;//OKcout << a.h << endl;//OK}};
};
int A::k = 1;
int main()
{A::B b;b.foo(A());return 0;
}

 感谢大佬支持,关于类和对象的知识目前就先讲到这里,如果有疑问或者是不对的地方,请大佬们指出。

相关文章:

C++初阶学习第五弹——类与对象(下)

类与对象&#xff08;上&#xff09;&#xff1a;C初阶学习第三弹——类与对象&#xff08;上&#xff09;-CSDN博客 类和对象&#xff08;中&#xff09;&#xff1a;C初阶学习第四弹——类与对象&#xff08;中&#xff09;-CSDN博客 一.赋值运算符重载 1.1 运算符重载 C为…...

最低工资标准数据(2001-2023年不等)、省市县,整理好的面板数据(excel格式)

时间范围&#xff1a;2001-2022年 具体内容&#xff1a;一&#xff1a;最低工资数据标准时间&#xff1a;2012-2021包含指标&#xff1a; 省份城市/区县小时最低工资标准&#xff08;非全日制&#xff09;月最低工资标准实施日期 样例数据&#xff1a; 二&#xff1a;各省最低…...

计算机毕业设计选题推荐-戏曲文化体验系统-Java/Python项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…...

【深度学习】CosyVoice,论文

CosyVoice_v1.pdf 文章目录 CosyVoice: A Scalable Multilingual Zero-shot Text-to-speech Synthesizer based on Supervised Semantic Tokens摘要1 引言2 CosyVoice: 使用监督语义标记的可扩展TTS模型2.1 用于语音的监督语义标记2.2 用于TTS的大型语言模型2.3 最优传输条件流…...

PHP8.3.9安装记录,Phpmyadmin访问提示缺少mysqli

ubuntu 22.0.4 腾讯云主机 下载好依赖 sudo apt update sudo apt install -y build-essential libxml2-dev libssl-dev libcurl4-openssl-dev pkg-config libbz2-dev libreadline-dev libicu-dev libsqlite3-dev libwebp-dev 下载php8.3.9安装包 nullhttps://www.php.net/d…...

[译] 深入浅出Rust基金会

本篇是对 RustConf 2023中的Rust Foundation: Demystified这一视频的翻译与整理, 过程中为符合中文惯用表达有适当删改, 版权归原作者所有. 大家好,我是Sage Griffin,我的代词是they/them。我今天来这里是要谈谈Rust基金会。 要了解基金会实际做什么,我们需要理解美国国内税收…...

Postman:API开发与测试的强大伴侣

在当今的数字化时代&#xff0c;API&#xff08;应用程序编程接口&#xff09;已成为不同软件系统之间通信的桥梁&#xff0c;它们如同数字世界的“翻译官”&#xff0c;使得数据和服务能够在不同的平台和应用程序之间无缝流动。然而&#xff0c;API的开发、测试和维护并非易事…...

Web应用的视界革命:WebKit支持屏幕方向API的深度解析

Web应用的视界革命&#xff1a;WebKit支持屏幕方向API的深度解析 在现代Web应用开发中&#xff0c;屏幕方向的适应性是一个重要的考虑因素。屏幕方向API&#xff08;Screen Orientation API&#xff09;提供了一种方法&#xff0c;允许Web应用知道并响应屏幕的方向变化&#x…...

【前端】一文带你了解 CSS

文章目录 1. CSS 是什么2. CSS 引入方式2.1 内部样式2.2 外部样式2.3 内联样式 3. CSS 常见选择器3.1 基础选择器3.1.1 标签选择器3.1.2 类选择器3.1.3 id 选择器3.1.4 通配符选择器 3.2 复合选择器3.2.1 后代选择器 4. CSS 常用属性4.1 字体相关4.2 文本相关4.3 背景相关4.4 设…...

IT服务运营管理中的关键考核指标

IT服务运营过程中常见的关键考核指标体现在人员、技术、资源、过程、质量等要素中&#xff0c;下面把常见的考核项目、计算方式、考核周期罗列如下&#xff0c;本考核指标主要用于对IT服务运营单位或部门的考核。 IT服务运营管理关键考核指标 要素考核项目计算方式常见考核周期…...

复习C语言从源文件.C到二进制.bin或可执行文件.exe文件的流程

...

如何恢复硬盘里删除的数据?硬盘数据恢复真的可靠吗?2024最新解答!

在日常的计算机使用中&#xff0c;我们时常会不小心删除硬盘中的重要数据&#xff0c;这时候&#xff0c;数据恢复就显得尤为重要。本文将介绍几种恢复硬盘里删除数据的方法&#xff0c;并探讨硬盘数据恢复的可靠性&#xff0c;提供2024年的最新解答。 一、什么是电脑硬盘&…...

Android Studio的新界面,怎么切换回老界面

将勾选的 Enable new UI 取消掉即可...

怎么用U盘重装系统

在使用电脑的过程中&#xff0c;难免会遇到系统故障、运行缓慢等问题。当这些问题严重影响使用电脑的体验时&#xff0c;重装系统往往是一个有效的解决办法。用U盘重装系统是一种简单快捷的方法&#xff0c;本文将详细介绍如何使用U盘来重装系统&#xff0c;帮助大家轻松完成这…...

Spring事件快速上手

文章目录 应用场景核心接口使用步骤异步事件事件排序 Spring 事件&#xff08;Application Event&#xff09;是 Spring 框架中实现观察者模式的一种方式&#xff0c;可以通过发布者和监听器来处理事件&#xff0c;常用于类之间解耦合、异步操作。 观察者模式&#xff1a;观察者…...

java算法递归算法练习-数组之和

简单找个题目练习一下递归算法&#xff0c;输入一组数组&#xff0c;使用递归的方法计算数组之和。其实这个题目&#xff0c;用循环的方式也很简单就能解决&#xff0c;直接循环遍历一下相加就行了&#xff0c;但是我们用来练习一下递归。 先来找基线条件和递归条件 基线条件…...

在kdevelop中运行程序并调试

补充前序知识&#xff1a; 1.CMakeLists.txt文件中&#xff0c;如下图&#xff0c;第一行生成的是静态库文件&#xff08;我们前一讲所使用的&#xff09;&#xff0c;第二行是动态库文件。 静态库与动态库&#xff1a; 静态库&#xff08;Static Libraries&#xff09; 定义…...

MySQL数据库-SQL编程

一、触发器 1.触发器简介 触发器&#xff08;trigger&#xff09;是一个特殊的存储过程&#xff0c;它的执行不是由程序调用&#xff0c;也不是手工启动&#xff0c;而是由事件来触发&#xff0c;比如当对一个表进行操作&#xff08; insert&#xff0c;delete&#xff0c; u…...

TypeError: Components is not a function

Vue中按需引入Element-plus时&#xff0c;报错TypeError: Components is not a function。 1、参考Element-plus官方文档 安装unplugin-vue-components 和 unplugin-auto-import这两款插件 2、然后需要在vue.config.js中配置webPack打包plugin配置 3、重新启动项目会报错 T…...

GuLi商城-商品服务-API-平台属性-销售属性维护

公用之前的接口&#xff0c;改下入参&#xff1a;...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

爬虫基础学习day2

# 爬虫设计领域 工商&#xff1a;企查查、天眼查短视频&#xff1a;抖音、快手、西瓜 ---> 飞瓜电商&#xff1a;京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空&#xff1a;抓取所有航空公司价格 ---> 去哪儿自媒体&#xff1a;采集自媒体数据进…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

初学 pytest 记录

安装 pip install pytest用例可以是函数也可以是类中的方法 def test_func():print()class TestAdd: # def __init__(self): 在 pytest 中不可以使用__init__方法 # self.cc 12345 pytest.mark.api def test_str(self):res add(1, 2)assert res 12def test_int(self):r…...

4. TypeScript 类型推断与类型组合

一、类型推断 (一) 什么是类型推断 TypeScript 的类型推断会根据变量、函数返回值、对象和数组的赋值和使用方式&#xff0c;自动确定它们的类型。 这一特性减少了显式类型注解的需要&#xff0c;在保持类型安全的同时简化了代码。通过分析上下文和初始值&#xff0c;TypeSc…...