从入门到精通C++之类和对象(续)

news2024/12/24 22:03:32

目录

  • 初始化列表
  • 构造函数?拷贝构造?
  • 浅谈explicit关键字
    • 友元
  • 内部类
  • static成员
  • 总结

在这里插入图片描述

初始化列表

引入初始化列表:简化代码,提高效率

在编程中,初始化列表是一种用于在创建对象时初始化成员变量的快捷方式。通过初始化列表,可以在对象构造时直接为成员变量赋值,而无需在构造函数体内进行赋值操作。这不仅使代码更简洁清晰,还可以提高程序的执行效率。

在本文中,我们将深入探讨初始化列表的概念及其在不同编程语言中的应用。我们将介绍初始化列表的语法结构,并通过具体的示例代码演示如何在常见的编程语言中使用初始化列表。无论您是初学者还是有一定经验的开发者,本文都将为您带来有价值的信息。

初始化列表的格式

class AA
{
public:
	AA(int n)
		:_a(n)
		,_b(n)
	{}
private:
	int _a;
	int _b;
};

d队列的初始化列表

	MyQueue(int n,int &rr)
		:_pushst(n)//调用构造函数
		, _popst(n)
		,_size(0)
		{}

注意
1、对于上面的初始化列表,_pushst_popst是自定义类型,所以后面加个括号其实就是调用它的构造函数,我们可以这样理解

2、如果我们要初始化const修饰的变量时,只能在初始化列表中初始化,因为const修饰的变量具有常性,所以只能在初始化列表中初始化

3、当我们要初始化一个成员变量是引用时,也必须在初始化列表中初始化

注意:初始化列表是成员变量定义的地方,而类中的成员变量只是成员变量的声明

如果我们不写初始化列表会生成初始化列表吗?

答案是肯定的,我们可以在成员变量声明的时候给一些缺省参数,我们可以定义一个类,然后用调试器进行调试,在调试中我们可以发现,我们进入这个类的时候会直接跳到缺省参数的那几行,我们可以打开监视器进行观察,也可以看见,类中的成员就是用缺省值进行初始化的
在这里插入图片描述

构造函数?拷贝构造?

int main()
{
	AA a1(1);//构造函数
	AA a2 = a1;//拷贝构造
	AA a3 = 1;//?
	return 0;
}

第一个是构造函数第二个是拷贝构造,那第三个是什么呢?

第三个是隐式类型转换
在C语言中下面代码会生成一个临时变量

double b=3.3;
int a=b;

对于上面代码会生成一个临时变量,b先生成一个临时变量tmp,tmp是int类型,然后tmp再赋值给a

在这里插入图片描述
所以回归正传,刚刚我们用一个类等于一个数字,其实是一个隐式类型转换,本质是1先调用构造函数创建一个tmp的对象,然后再利用tmp再拷贝拷贝构造给a3

如果用AA&a3会报错,因为1具有常性,a3是tmp的引用a3可以修改,但是因为常性不能修改,所以会报错,这里就是权限的放大,所以我们可以在前面加一个const

	const AA& a3 = 1;

通过下面题目来引入一个初始化列表的规则

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();
}
	A. 输出1  1
	B.程序崩溃
	C.编译不通过
	D.输出1  随机值

对于上面这道题肯定不会选择A,因为往往这种题,都不可能这么直接,更不可能选择B,因为B是程序崩溃,往往程序崩溃只会出现在野指针和空指针中,只有从c和D中选,肯定可以排除C因为不可能编译错误。

从上面的题目中我们就可以得到一个规则,初始化列表的初始化顺序与初始化列表的顺序无关,只与声明时的顺序有关

上面我们讨论的是只有一个参数的时候的初始化,当有两个参数时我们应该如何传参呢

两个参数的参数列表的传参和数组类似

class AA
{
public:
	AA(int n = 1, int m = 2)
		:_a(n)
		, _b(n)
	{}
private:
	int _a = 1;
	int _b = 0;
};
int main()
{
	AA a1(1);
	AA a2 = a1;
	const AA& a3 = 1;
	AA aa4 = { 1,2 };
	return 0;
}

当有两个参数的时候,就可以利用C99的语法进行初始化,其实等号也可以省略,最好把等号加上

浅谈explicit关键字

前面我们谈了隐式类型转换,如果我们不想进行隐式类型转换可以在函数前面加一个explicit关键字

智能指针是explicit关键字的使用场景

友元

友元函数就是全局函数,只不过是写在了类中,友元函数可以直接访问类中的私有成员变量,下面我们简单的写一个友元函数作为示范:
在声明中可以像下面这样声明:

	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in, Date& d);

一般情况下,我们都会把友元函数的声明声明在类中的最前面,声明完了之后,友元函数在定义中还是像正常函数一样写,前面不用加friend

友元的特性

  1. 友元关系是单向的,不具有交换性。
    比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接
    访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。
  2. 友元关系不能传递
    如果C是B的友元, B是A的友元,则不能说明C时A的友元。
  3. 友元关系不能继承,在继承位置再给大家详细介绍。

出了友元函数还有友元类,在友元类中我们可以用另一个类中的私有成员变量

下面是友元类的声明

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

内部类

内部类就是、一个类中定义另一个类
内部类的特性:内部类是外部类的天生的友元类,内部类可以随意访问外部类的成员变量

注意:内部类也是一个单独的类,唯一的区别是受到了外部类域的限制,所以计算外部类的大小的时候,不需要加上内部类的大小,只需要算外部类的成员变量的大小即可

如果内部类定义在Public中则外面也可以访问,如果内部类定义在private中则只有类的内部才能访问

static成员

我们来计算一下下面的类的大小:

class BB
{
public:

private:
	int _b1;
	static int _b1;
};

注意成员变量不存函数和静态变量,一个存放在代码区,一个存放在静态区,所以在计算类的大小的时候,我们也不计算static修饰的成员变量

在C语言中我们知道,static修饰的变量只初始化一次,且在定义的时候初始化,因为在类中的是声明所以我们不应该给成员变量缺省值,也不应该将static修饰的成员变量放在初始化列表中进行初始化

正确的初始化方法如下:

class BB
{
public:

private:
	int _b1;
	static int _b1;
};
int BB::_b1 = 1;
int main()

特性

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

总结

通过本文的介绍,我们深入探讨了几个编程中的关键概念:友元、初始化列表、静态成员变量以及内部类。友元使得类之间的访问更加灵活,但也需要慎重使用以保持封装性;初始化列表能够简化对象的构造过程,提高代码效率;静态成员变量共享于类的所有对象,是实现全局数据共享和类特性存储的有效方式;内部类则可以在一个类的内部定义另一个类,便于组织和封装相关的功能。

深入理解这些概念对于成为一名优秀的程序员至关重要。熟练掌握它们不仅可以提高代码的质量和效率,还能够拓展我们的编程思维,使我们更加灵活地应对不同的问题和挑战。

在实际编程中,我们应该根据具体情况合理运用这些概念,从而编写出清晰、高效且易于维护的代码。希望本文能够为您在编程学习和实践中提供一些帮助和启发。让我们继续不断学习和探索,成为更加优秀的程序员!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

神仙级Python入门教程(超级详细),从零基础入门到精通!!

关于Python学习指南 学好 Python 不论是就业还是做副业赚钱都不错&#xff0c;但要学会 Python 还是要有一个学习规划。最后给大家分享一份全套的 Python 学习资料&#xff0c;给那些想学习 Python 的小伙伴们一点帮助&#xff01; 包括&#xff1a;Python激活码安装包、Pyth…

RAG原理详解

什么是RAG 检索增强生成&#xff08;Retrieval Augmented Generation&#xff0c;简称RAG&#xff09;为大型语言模型&#xff08;LLMs&#xff09;提供了从某些数据源检索到的信息&#xff0c;以此作为生成答案的基础。简而言之&#xff0c;RAG是搜索LLM提示的结合&#xff0…

新标准日本语 课后练习

自学错误可能较多&#xff0c;听力题不需要听力的就没听录音 第二十課 スミスさんはピアノを弾くことができます 練習&#xff11;&#xff0d;&#xff11; &#xff11;張さんは日本の歌を歌うことができます 张先生会唱日本歌 &#xff12;小野さんは自転車に乗ることがで…

Doris Manager 24.0 版本正式发布!

Cluster Manager for Apache Doris&#xff08;简称 Doris Manager&#xff09;是 SelectDB 推出的管理运维 Apache Doris 集群的工具。用户可以轻松通过该工具部署和接管集群&#xff0c;实时查看集群的运行状态和详情&#xff0c;快捷地对集群进行扩缩容、升级及重启操作。同…

App Inventor 2 计时器组件,时间相关的用法都在这里

1、计时器在界面设计中的哪里&#xff1f; 2、计时器怎么启动&#xff1f; 默认计时器是自动启用的&#xff0c;也可程序控制它的属性“启用计时”和“不启用计时”。 3、怎么确定计时器执行没&#xff1f; 定一个数字全局变量&#xff0c;计时方法里面自增&#xff0c;然后输…

2024 CVPR AIGC集合

完全外行&#xff0c;不建议参考 一、3D重建 PointAvatar: Deformable Point-based Head Avatars from Videos 对原始颜色进行解纠缠&#xff0c;得到固有反射和相关阴影。 基于可变形点云对表情、颜色、位置等信息进行建模。 总结&#xff1a;可以看作是对局部像素的分解与扩…

gcc原理和使用

gcc gcc是什么 GCC&#xff0c;全称 GNU Compiler Collection&#xff08;GNU 编译器套件&#xff09;&#xff0c;是一套功能强大的编程语言编译器&#xff0c;由自由软件基金会&#xff08;Free Software Foundation, FSF&#xff09;作为GNU项目的一部分开发和维护。它最初…

【文献分享】机器学习 + 分子动力学 + 第一性原理 + 电导率 + 微观结构

​【文献分享】机器学习 分子动力学 第一性原理 电导率 微观结构 分享一篇关于机器学习 分子动力学 第一性原理 电导率 微观结构的文章。 感谢论文的原作者&#xff01; 关键词&#xff1a; 1. Machine learning force field 2. Molecular dynamics 3. Solid state …

刷题日记——质因数的个数

题目 分析&#xff08;从质数的判断角度出发&#xff09;&#xff08;递归&#xff09; 判断n是否是质数需要&#xff1a; 遍历&#xff0c;i从2开始到sqrt(n)&#xff0c;每次判断n是否能整除i&#xff0c;若能则不是质数&#xff0c;若不能则是 思路&#xff1a; 先判断n…

你也许不知道的 Confluence 快捷操作

Confluence 是一种企业知识管理和协作平台&#xff0c;用于创建、共享和组织团队的文档、知识和想法。它支持团队成员进行实时协作、评论和编辑文档&#xff0c;提供了强大的搜索功能&#xff0c;方便用户快速找到需要的信息。 Confluence 快捷键解析&#xff0c;标注了对应的…

SpringBoot多数据源(二)

SpringBoot多数据源AbstractRoutingDataSource&#xff08;二&#xff09; 1.多数据源配置2.多数据源调用流程3.实现 1.多数据源配置 spring-jdbc模块提供AbstractRoutingDataSource,其内部可以包含了多个DataSource&#xff0c; 然后在运行时来动态的访问数据库 2.多数据源…

新型大数据架构之湖仓一体(Lakehouse)架构特性说明——Lakehouse 架构(一)

文章目录 为什么需要新的数据架构&#xff1f;湖仓一体&#xff08;Lakehouse&#xff09;——新的大数据架构模式同时具备数仓与数据湖的优点湖仓一体架构存储层计算层 湖仓一体特性单一存储拥有数据仓库的查询性能存算分离开放式架构支持各种数据源类型支持各种使用方式架构简…

1.总结串口的发送和接收功能使用到的函数2.总结DMA的作用,和DMA+空闲中断的使用方式3.使用PWM+ADC光敏电阻完成光控灯的实验

1.总结串口的发送和接收功能使用到的函数 串口发送函数&#xff1a;HAL_StatusTypeDef HAL_UART_Transmit(UART_HandleTypeDef *huart, const uint8_t *pData, uint16_t Size, uint32_t Timeout) UART_HandleTypeDef *huart&#xff1a;指定要使用的串口 const uint8_t *pData&…

数智时代的AI人才粮仓模型解读白皮书(2024版)

来源&#xff1a;极客邦 自 2023 年上半年起&#xff0c;ChatGPT 等大模型技术蓬勃发展&#xff0c;AI 技术不断突破边界&#xff0c;展现 出惊人的潜力和发展速度。从早期的逻辑推理、专家系统&#xff0c;到如今的深度学习、神经网络&#xff0c; AI 技术显著缩小了科学与实…

宝宝洗衣机买几公斤?四款精心挑选实用婴儿洗衣机推荐

家里有孩子的&#xff0c;条件允许的话&#xff0c;婴儿洗衣机还是非常有必要买的。由于宝宝的年纪还小&#xff0c;使得宝宝的皮肤比较娇嫩&#xff0c;与成人衣物分开洗护&#xff0c;可以为宝宝带来更加健康的生长环境&#xff0c;并且可以避免与大人衣物混洗所带来的细菌的…

线圈、寄存器、存储区代号、功能码 案例说明

线圈和寄存器 表示数据类型 线圈&#xff1a;表示Boolean数据类型 寄存器&#xff1a;表示非Boolean数据类型&#xff0c;用来暂时存放参与运算的数据和运算结果&#xff0c;具有接收数据、存放数据和输出数据的功能。 ModbusRTU 读输出线圈 存储区代号 0区 功能码 0x01 读输入…

【过程11】——教育被点燃的路上

这里写目录标题 一、背景二、过程1.两年四十万的认知改变2.三年打工仔的经历改变3.一年计算机的人生蜕变4.后面的展望 三、总结 一、背景 人生在世&#xff0c;对于一些事情的笃信笃行&#xff1b;背后真的会有莫大无以言表的波涛。 这个事情到现在已经五年半左右时间了&#…

数据的插入、修改和删除

一、 插入数据 1. 向表中所有字段插入数据 &#xff08;1&#xff09; 指定所有字段及其相对应的值 insert into 表名(字段1&#xff0c;字段2&#xff0c;……) values(字段值1&#xff0c;字段值2&#xff0c;……);**【案例】**向goods表中插入一条新记录 步骤1&#xff…

C语言【数组】

一、数组基本语法 1. 什么是数组 数组是c语言的一种数据结构&#xff0c;用于存储一组具有相同数据类型的数据&#xff1b; 数组中每个元素可以通过下标进行访问&#xff0c;索引从0开始&#xff0c;最大值为数组长度-1。 2. 数组的使用 类型 数组名[元素个数]; int arr[5]…

网络基础-TCP/IP和OSI协议模型

一、OSI和TCP/IP模型 二、OSI七层模型 三、TCP/IP模型 参考&#xff1a;https://www.cnblogs.com/f-ck-need-u/p/7623252.html