✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿
🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟
🌟🌟 追风赶月莫停留 🌟🌟
🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀🍀
🌟🌟 平芜尽处是春山🌟🌟
🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟🌟
🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿🌿
✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨✨
✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅✅
🍋类与对象
- 🍑构造函数(知识点补充)
- 🍍初始化列表
- 🍍explicit关键字
- 🍑static成员
- 🍍概念
- 🍍特性
- 🍑友元
- 🍍友元函数
- 🍍友元类
- 🍑内部类
- 🍍概念
- 🍍特性
- 🍑类与对象的理解
🍑构造函数(知识点补充)
上篇已经讲到了构造函数的大部分知识点,在这里有几个新知识点需要大家了解。
🍍初始化列表
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。
我们已经知道了默认构造函数:
上篇中已经讲到,全缺省构造函数也是属于默认构造函数。
初始化列表也是与构造函数有关:
上图就是初始化列表的写法,初始化列表主要是在构造函数中实现。
大家注意书写格式。
平常的我们在函数体内初始化,那叫函数体初始化。两者各有各的优点和缺点。
引用和const和自定义类型没有构造函数时等修饰需要在初始化列表定义,不能在函数体内定义。两种写法可以混着使用,符合规则即可。
总结:
- 必须有定义的地方显示初始化“引用、const、没有默认构造的自定义成员类型”。
- 有些自定义成员想要显示初始化,可以自己控制。
- 初始化列表初始化的顺序是按声明顺序走的。
🍍explicit关键字
构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用。
大家应该都知道类型转换,平常的类型转换我们都看到,比如:
int a = 1;
float c = (float)a;
c是float类型,a是int类型,而当我们需要把a的值赋给c时,就需要先把a转换成float类型,然后再传给c。
再看看这个程序:
在这个程序当中,我没有给a进行类型转换,就已经传给c了,并且运行成功了。这是为什么呢? 这是因为在系统内部进行了隐式类型转换,实际上在a传过去的那一刻,a已经是float类型了,我们看不到。
explicit关键字它的功能也与这隐式转换有关,不过它是起限制隐式转换的作用。
接下来看这个代码:
大家应该很疑惑,为什么100可以直接赋给Add类的vv,100是int类型,而vv是Add类型,并且是一个类。其实在这里是进行了隐式转换。
如:
从100赋给vv是分为两步,第一步就是构造,然后中间有一个Add类的临时变量来接受100,此时100就从int类型到Add类型的转换,第二步就是拷贝构造,临时变量把100传给了vv。
大家可以看看显示转换的写法:
//第一种写法
Add vv = Add(100);
//第二种写法
Add vv(100);
上面就是显示转换的写法。
加了explicit后,就会报错,explicit限制了隐式类型的转换。
显示转换没有收到影响。
用explicit修饰构造函数,将会禁止构造函数的隐式转换。
🍑static成员
🍍概念
声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的成员函数,称之为静态成员函数。
静态成员有一个显著的特点,那就是它们不属于某一个特定的对象,而是属于整个类,也就是说,无论创建了多少个类的对象,这些对象都共享同一个静态成员。因此,静态成员可以被视为连接各个对象的桥梁。
当然还有一点,静态成员变量一定要在类外进行初始化。
🍍特性
- 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区
- 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明
- 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问
- 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
- 静态成员也是类的成员,受public、protected、private 访问限定符的限制
🍑友元
友元是一种定义在类外部的普通函数或类,但它需要在类体内进行说明,并在说明时前面加上关键字“friend”,以区别于该类的成员函数。尽管友元不是类的一部分,但它可以访问类中的私有成员,从而打破了类的封装性和隐藏性。这种设计的目的通常是为了提高程序的运行效率,减少类型和安全性检查及调用的时间开销。
友元分为友元函数和友元类。
🍍友元函数
- 友元函数可以直接访问类的私有成员。
- 它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。
注意:
- 友元函数可访问类的私有和保护成员,但不是类的成员函数
- 友元函数不能用const修饰
- 友元函数可以在类定义的任何地方声明,不受类访问限定符限制
- 一个函数可以是多个类的友元函数
- 友元函数的调用与普通函数的调用原理相同
🍍友元类
友元类是一种特殊的类关系,在C++中定义,它允许一个类(友元类)访问另一个类(宿主类)的私有成员(包括私有成员变量和私有成员函数)。当一个类作为另一个类的友元时,这意味着这个类的所有成员函数都是另一个类的友元函数,可以访问另一个类中的隐藏信息。
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
- 单向性:友元关系是单向的,不具有交换性。即,如果类B是类A的友元,类A不一定是类B的友元。这是因为在类中是否有相应的声明决定的。
- 非传递性:友元关系也不具有传递性。即,如果类B是类A的友元,类C是类B的友元,类C不一定是类A的友元。这同样取决于类中是否有相应的声明。
- 访问权限:友元类可以访问宿主类的所有成员,包括私有成员和保护成员,而不受类的访问限定符限制。
- 声明位置:友元的声明通常放在类的定义中,位于public、protected和private之外。
🍑内部类
🍍概念
在C++中,内部类(也称为嵌套类)是定义在另一个类的作用域内的类。内部类可以是另一个类的成员,也可以定义在另一个类的函数或作用域块中。
内部类就是外部类的友元类,参见友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。
🍍特性
- 内部类可以定义在外部类的public、protected、private都是可以的。
- 注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。
- sizeof(外部类)=外部类,和内部类没有任何关系。
如:
B天生就是A的友元,但A不是B的友元。
🍑类与对象的理解
现实生活中的实体计算机并不认识,计算机只认识二进制格式的数据。如果想要让计算机认识现
实生活中的实体,用户必须通过某种面向对象的语言,对实体进行描述,然后通过编写程序,创建对象后计算机才可以认识。比如想要让计算机认识洗衣机,就需要:
- 用户先要对现实中洗衣机实体进行抽象—即在人为思想层面对洗衣机进行认识,洗衣机有什么属性,有那些功能,即对洗衣机进行抽象认知的一个过程
- 经过1之后,在人的头脑中已经对洗衣机有了一个清醒的认识,只不过此时计算机还不清楚,想要让计算机识别人想象中的洗衣机,就需要人通过某种面相对象的语言(比如:C++、Java、Python等)将洗衣机用类来进行描述,并输入到计算机中
- 经过2之后,在计算机中就有了一个洗衣机类,但是洗衣机类只是站在计算机的角度对洗衣机对象进行描述的,通过洗衣机类,可以实例化出一个个具体的洗衣机对象,此时计算机才能洗衣机是什么东西。
- 用户就可以借助计算机中洗衣机对象,来模拟现实中的洗衣机实体了。在类和对象阶段,大家一定要体会到,类是对某一类实体(对象)来进行描述的,描述该对象具有那些属性,那些方法,描述完成后就形成了一种新的自定义类型,才用该自定义类型就可以实例化具体的对象。
类与对象就在此结束了,接下来就算正式踏入C++大门了,祝各位好运!!!