[C++]类和对象,explicit,static,友元,构造函数——喵喵要吃C嘎嘎4
希望你开心,希望你健康,希望你幸福,希望你点赞!
最后的最后,关注喵,关注喵,关注喵,大大会看到更多有趣的博客哦!!!
喵喵喵,你对我真的很重要!
前言
佬佬催更,那就更吧!嗯~ o(* ̄▽ ̄*)o!
再谈构造函数
构造函数体赋值
在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值
class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};
虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化, 构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体 内可以多次赋值。
初始化列表
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括 号中的初始值或表达式
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
3. 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使 用初始化列表初始化。
class Time
{
public:
Time(int hour = 0):_hour(hour){cout << "Time()" << endl;}
private:int _hour;
};
class Date
{
public:Date(int day){}
private:int _day;Time _t;
};
int main()
{Date d(1);
}
4. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关
class A
{
public:A(int a):_a1(a),_a2(_a1){}void Print() {cout<<_a1<<" "<<_a2<<endl;}
private:int _a2;int _a1;
};
int main() {A aa(1);aa.Print();
}
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成员
声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的 成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化 面试题:实现一个类,计算程序中创建出了多少个类对象。
class A
{
public:A() { ++_scount; }A(const A& t) { ++_scount; }~A() { --_scount; }static int GetACount() { return _scount; }
private:static int _scount;
};
int A::_scount = 0;
void TestA()
{cout << A::GetACount() << endl;A a1, a2;A a3(a1);cout << A::GetACount() << endl;
}
特性
1. 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区
2. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明
3. 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问
4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
5. 静态成员也是类的成员,受public、protected、private 访问限定符的限制
友元
友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多 用。 友元分为:友元函数和友元类
友元函数
问题:现在尝试去重载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修饰 友元函数可以在类定义的任何地方声明,不受类访问限定符限制 一个函数可以是多个类的友元函数 友元函数的调用与普通函数的调用原理相同
友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
友元关系是单向的,不具有交换性。 比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time 类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。
友元关系不能传递 如果B是A的友元,C是B的友元,则不能说明C时A的友元。 友元关系不能继承,在继承位置再给大家详细介绍。
class Time
{friend class Date; // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类中的私有成
员变量
public:Time(int hour = 0, int minute = 0, int second = 0): _hour(hour)
, _minute(minute), _second(second){}private:int _hour;int _minute;int _second;
};
class Date
{
public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}void SetTimeOfDate(int hour, int minute, int second){// 直接访问时间类私有的成员变量_t._hour = hour;_t._minute = minute;_t._second = second;}private:int _year;int _month;int _day;Time _t;
};
内部类
概念:如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,它不属于外 部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。 注意:内部类就是外部类的友元类,参见友元类的定义,内部类可以通过外部类的对象参数来访问外部类中 的所有成员。但是外部类不是内部类的友元。 特性: 1. 内部类可以定义在外部类的public、protected、private都是可以的。
2. 注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。
3. sizeof(外部类)=外部类,和内部类没有任何关系。
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;
}
再次理解类和对象
现实生活中的实体计算机并不认识,计算机只认识二进制格式的数据。如果想要让计算机认识现实生活中的 实体,用户必须通过某种面向对象的语言,对实体进行描述,然后通过编写程序,创建对象后计算机才可以 认识。比如想要让计算机认识洗衣机,就需要: 1. 用户先要对现实中洗衣机实体进行抽象---即在人为思想层面对洗衣机进行认识,洗衣机有什么属性,有 那些功能,即对洗衣机进行抽象认知的一个过程 2. 经过1之后,在人的头脑中已经对洗衣机有了一个清醒的认识,只不过此时计算机还不清楚,想要让计 算机识别人想象中的洗衣机,就需要人通过某种面相对象的语言(比如:C++、Java、Python等)将洗衣 机用类来进行描述,并输入到计算机中 3. 经过2之后,在计算机中就有了一个洗衣机类,但是洗衣机类只是站在计算机的角度对洗衣机对象进行 描述的,通过洗衣机类,可以实例化出一个个具体的洗衣机对象,此时计算机才能洗衣机是什么东西。 4. 用户就可以借助计算机中洗衣机对象,来模拟现实中的洗衣机实体了。 在类和对象阶段,大家一定要体会到,类是对某一类实体(对象)来进行描述的,描述该对象具有那些属性, 那些方法,描述完成后就形成了一种新的自定义类型,才用该自定义类型就可以实例化具体的对象。
总结
人生苦短,一天当作两天卷!
每天都要敲3个小时的代码!
坚持就好!
希望你开心,希望你健康,希望你幸福,希望你点赞!
最后的最后,关注喵,关注喵,关注喵,大大会看到更多有趣的博客哦!!!
喵喵喵,你对我真的很重要!
相关文章:

[C++]类和对象,explicit,static,友元,构造函数——喵喵要吃C嘎嘎4
希望你开心,希望你健康,希望你幸福,希望你点赞! 最后的最后,关注喵,关注喵,关注喵,大大会看到更多有趣的博客哦!!! 喵喵喵,你对我真的…...

物联网的商业模式洞察
大约在十年前(2014年11月),全球知名管理思想家、哈佛商学院教授迈克尔波特与PTC前首席执行官吉姆赫普尔曼,在《哈佛商业评论》上联合撰写了一篇备受赞誉的文章,题为《智能互联产品如何改变竞争》。在这篇文章中&#x…...

智能指针基础知识【C++】【RAII思想 || unique_ptr || shared_ptrweak_ptr || 循环引用问题】
目录 一,为什么需要智能指针 二,内存泄露的基本认识 1. 内存泄露分类 2. 常见的内存检测工具 3,如何避免内存泄露 三,智能指针的使用与原理 1. RAII思想 2. 智能指针 (1. unique_ptr (2. shared_…...

leetcode:反转链表II 和k个一组反转链表的C++实现
反转链表II 问题描述 给你单链表的头指针 head 和两个整数 left 和 right ,其中 left < right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。 ListNode* reverseBetween(ListNode* head, int left, int right) {ListNode *…...

ERD Online 快速启动指南:代码下载到首次运行的全流程攻略 ️
🚀 一、代码下载 ERD online前端代码正常拉取即可👌 后端代码含有子模块,拉取命令如下: git clone --recurse-submodules https://github.com/www-zerocode-net-cn/martin-framework.git 🛠️ 二、代码构建 dz…...

c++ 11 新特性 不同数据类型之间转换函数之const_cast
一.不同数据类型之间转换函数const_cast介绍 const_cast是C11中引入的一种类型转换操作符,用于修改类型的const或volatile属性。const_cast的主要用途是移除对象的常量性,它是唯一具有此能力的C风格的转型操作符。在C11中,const_cast可以完成…...

C++从零开始的打怪升级之路(day45)
这是关于一个普通双非本科大一学生的C的学习记录贴 在此前,我学了一点点C语言还有简单的数据结构,如果有小伙伴想和我一起学习的,可以私信我交流分享学习资料 那么开启正题 今天分享的是关于二叉树的题目 1.根据二叉树创建字符串 606. 根…...

小鹅通前端实习一面
总时长35分钟,自我介绍开始 1.js和c特点上的差异; 2.js数组去重 3.js的数据类型 4.js的引用类型和值类型的差别 5.讲一下js的网络请求 6.对前端三件套和框架的理解 7.一个html文档的结构是怎样的 8.head和body的区别 9.一个页面的加载顺序(ht…...

ArrayList常用API
常见方法 add 增remove 删set 改get 查clear 清空元素size 长度isEmpty 为空判断 用法 // String就是泛型 这种使用方法对于限制类型很有用 ArrayList<String> arrayList new ArrayList<>();// add 添加元素 返回的是boolean 代表是否添加成功 arrayList.add(&qu…...

Chrome安装Axure插件
打开原型目录/resources/chrome,重命名axure-chrome-extension.crx,修改后缀为rar,axure-chrome-extension.rar 解压到axure-chrome-extension目录打开Chrome,更多工具->扩展程序,打开开发者模式,选择加…...

【AI+应用】模仿爆款视频二次创作短视频操作步骤
本来不想水这篇的, 剪辑软件估计很多人用的比我还6。 今天自己遇到1个需求,我看到一篇公众号文章的视频觉得有意思,但视频有点长,我没带耳机看视频的习惯,就想着能不能下载下来, 提取视频的音频转为文字&am…...

HTML使用
文章目录 一、简介二、HTML快速入门三、基础标签四、图片、音频、视频标签五、超链接标签六、列表标签七、表格标签八、布局标签九、表单标签十、表单向标签 一、简介 二、HTML快速入门 <html><head><title>你好</title></head><body>再…...

通过联合部署DDoS高防和WAF提升网站防护能力
如果您的网站遭受的攻击既有流量型攻击,又混杂精巧的Web应用层攻击时(例如SQL注入、跨站脚本攻击、命令注入等)时,推荐您组合使用阿里云DDoS高防和Web 应用防火墙 WAF(Web Application Firewall)࿰…...

具体挫折现象的发生以及解法思考:您如果继续不问的话,严重重责就容易来
一 积极想方设法的寻找扭转劣势的方式方法; 目前对于第一条的践行,主要还是依靠打工做事赚取收入。至于个人业务,只能往后推,往后延迟。因为不管您目前居住的环境,还是个人条件都不行,所以无法实行个人业…...

Type-C接口PD协议统一:引领电子科技新纪元的优势解析
在电子科技日新月异的今天,充电接口的统一化已经成为了业界的一大趋势。其中,Type-C接口凭借其传输速度快、使用便捷等优点,迅速成为了市场上的主流选择。而PD(Power Delivery)协议的统一,更是为Type-C接口…...

探讨2024年AI辅助研发的趋势
一、引言 随着科技的飞速发展,人工智能(AI)已经成为当今时代最具变革性的技术之一。AI的广泛应用正在重塑各行各业,其中,AI辅助研发作为科技和工业领域的一大创新热点,正引领着研发模式的深刻变革。从医药…...

Java对接海康威视摄像头实现抓图
目录 一、下载SDK 二、拷贝示例代码 三、拷贝库文件 四、运行Demo 五、抓图业务 六、调参 七、发布Linux正式环境 一、下载SDK 海康开放平台 二、拷贝示例代码 三、拷贝库文件 这时候直接运行ClientDemo会报错,因为缺失库文件! 四、运行Demo …...

浏览器一键重新发起请求
一、需求场景 在前端开发过程中,经常会需要重新请求后台进行代码调试,之前的常规方法是刷新浏览器页面或者点击页面进行交互,这样对多个请求的场景就很方便,但是往往很多时候我们只是单纯的想重新发起一个请求(多个请求…...

一起来读李清照
当然先祝各位女生节日快乐🎁🎁啦。 但是呢,今天,我们不聊技术,来聊点其他的。 大家都知道今天是三八妇女节,三八妇女节的是中国人的叫法,也叫国际妇女节。是为了纪念妇女权利的运动&#…...

找出单身狗1,2
目录 1. 单身狗12. 单身狗2 1. 单身狗1 题目如下: 思路:一部分人可能会使用对数组排序,遍历数组的方式去找出只出现一次的数字,但这种方法的时间复杂度过高,有时候可能会不满足要求。 有一种十分简便的方法是使用异或…...

贝叶斯优化BiLSTM分类预测(matlab代码)
贝叶斯优化BiLSTM分类matlab代码 数据为Excel分类数据集数据。 数据集划分为训练集、验证集、测试集,比例为8:1:1 数据处理: 在数据加载后,对数据进行了划分,包括训练集、验证集和测试集,这有助于评估模型的泛化能力。 数据标…...

Linux运维:实现光盘开机自动挂载、配置本地yum源教程
Linux运维:实现光盘开机自动挂载、配置本地yum源教程 一、光盘开机自动挂载1、检查光驱设备2、创建挂载点3、编辑/etc/fstab文件4、测试挂载 二、配置本地yum源(挂载光盘或ISO文件)1、挂载ISO文件2、创建YUM仓库配置文件3、清理YUM缓存并测试 💖The Begi…...

C语言从入门到精通 第十二章(程序的编译及链接)
写在前面: 本系列专栏主要介绍C语言的相关知识,思路以下面的参考链接教程为主,大部分笔记也出自该教程。除了参考下面的链接教程以外,笔者还参考了其它的一些C语言教材,笔者认为重要的部分大多都会用粗体标注…...

即插即用篇 | YOLOv8 引入 ParNetAttention 注意力机制 | 《NON-DEEP NETWORKS》
论文名称:《NON-DEEP NETWORKS》 论文地址:https://arxiv.org/pdf/2110.07641.pdf 代码地址:https://github.com/imankgoyal/NonDeepNetworks 文章目录 1 原理2 源代码3 添加方式4 模型 yaml 文件template-backbone.yamltemplate-small.yamltemplate-large.yaml...

基于51单片机的数字频率计设计
基于51单片机的数字频率计设计 摘要: 本文深入探讨了基于51单片机的数字频率计设计方案与实践。该设计方案不仅实现了对输入信号频率的高精度测量,还通过直观的数字显示提供了便捷的读取方式。在电子测量领域,频率作为核心参数之一,其准确测量对于确保通信、音频处理、控…...

20240307-1-前端开发校招面试问题整理JavaScript
前端开发校招面试问题整理【1】——JavaScript 1、JavaScript 基础 Q:介绍 js 的基本数据类型? 基本类型(值类型):String,Number,Boolean,Null,Undefined,S…...

1.3 数据库系统的结构
目录 1.3.1 数据库系统模式的概念 1.3.2 数据库系统的三级模式结构 1. 模式 2. 外模式 3.内模式(也称存储模式) 1.3.3 数据库的二级映像功能与数据独立性 1.外模式/模式映像 2.模式/内模式映像 1.3.4 总结 模式 内模式…...

【Springer出版 · EI检索】| 第二届先进无人飞行系统国际会议(ICAUAS 2024)
会议简介 Brief Introduction 2024年第二届先进无人飞行系统国际会议(ICAUAS 2024) 会议时间:2024年6月14日-16日 召开地点:中国南昌 大会官网:ICAUAS 2024-2024 2nd International Conference on Advanced Unmanned Aerial Systems2024 2nd …...

RocketMQ快速入门_2. rocketmq 的应用场景、与其他mq的差异
0. 引言 之前我们讲解过rabbitMQ,本期我们将进入吞吐量更加强大的rocketMQ的学习。 1. 基础概念 如果你是刚接触MQ的同学,还不清楚消息队列的基础概念的,可以参考我之前这篇文章: https://wu55555.blog.csdn.net/article/deta…...

【Azure 架构师学习笔记】- Azure Private Endpoint
本文属于【Azure 架构师学习笔记】系列。 前言 公有云的其中一个特点是默认允许公网访问, 这就对企业环境带来风险,也是很多年前企业对公有云抵触的其中一个原因,现在这类问题已经很少,因为有了很多技术来确保云上的资源被安全地…...