C++ 类和对象 3

构造函数扩展

构造函数体内的赋值:构造函数一般是用于类对象的初始化的,但严谨来说并不是成员变量的初始化,内置类型的初始化是在生成的同时赋值而且仅有一次,但是在构造函数体内是能对成员变量进行多次赋值的。所以在函数体内的仅是赋值而不是初始化。

成员变量的初始化:在C++中有一些变量是只能使用初始化来赋值的,初始化之后改变量是无法被再次赋值的,这些变量就无法在构造函数体内完成赋值所以构造函数针对这些变量还有一个初始化列表。

这是一个完整的初始化列表的构造函数,这个构造函数的函数体是空的什么都没有完全依靠初始化列表完成对成员变量的初始化,列表的开始用:后面每一个成员用逗号隔开,列表中每个成员变量只能出现一次,类似变量的引用,const变量,自定义类型成员且没有默认构造函数的这类只能初始化的变量便可以使用初始化列表来初始化。

一般构造函数中能使用初始化列表初始化的都会尽量使用初始化列表,当然像需要有额外操作如开辟空间之类的也是可以在函数体中实现,构造函数会先走初始化列表然后再进入函数体,注意初始化列表的初始化顺序与我们写的初始化列表的成员变量的顺序无关而是按照在类中声明的顺序初始化的

这里我定义的顺序是_a->_b->_c那么只要包含这三个成员变量就肯定按照这个顺序初始化,无关初始化列表的顺序。

explicit关键字

内置类型中是存在隐式类型转化的在相近类型之间进行赋值的时候会通过隐式类型转化生成一个目标类型的中间变量再完成赋值,自定义类型当我们有全缺省构造函数或者除了一个参数没有默认值其余都有的构造函数或只有一个参数的构造函数的时候就可以发生赋值时的隐式类型转化,

这里我实现了一个单参数的构造函数当我用一个符合上面函数的值创建这个类对象的时候便会发生隐式类型转化同过这个构造函数创建一个_a为0的临时对象再调用赋值运算符重载来完成这次的自定义类型的赋值。

可是当我们使用隐式类型转化来创建新对象的时候其一这个代码的可读性就不太好,C++是从C中拓展而来的这种类型相差如此大的变量类型能如此不符合C语言的习惯,同时效率上是有缺失的,这里先是构造了一个临时对象再进行赋值构造而我们可以直接构造的不需要走第二次的赋值构造的,若是一些构造有些消耗的都会些效率上的损失。

那么我们这里在声明这个构造函数的时候就可以加上explicit关键字

这样子就限定了不能进行隐式类型转化也就杜绝了这种代码的出现

static成员

通过static修饰的变量和函数会存放在静态区,并且其相当于全局的,拥有和全局变量和函数一样的作用域和生命周期。

若是我们在类中声明了静态成员与一般变量函数一样也是存放在静态区的,并且是类中静态成员函数是没有this指针的所以也不能调用类中的非静态成员函数和非静态变量,静态成员变量还不能在类中定义只能在外部定义,类中只能对静态成员变量进行声明,在进行声明时不需要加static修饰。

类中的静态成员是被所有类对象所公有的,无论存在多少个类对象,静态成员都仅有一份,每个对象访问的都是同一个静态成员。

友元

类使用划分公有,私有,保护来让类获得封装的特性,但可能会有特定的函数或者类需要访问这些隐藏的数据或函数的情况,这里C++就为这种情况设计出了友元的概念,我们可以将函数或者其他类设置成某一个类的友元函数或者友元类,这个函数或者类就可以如同成员函数一样访问类中的所有成员。

友元函数

在C++中我们打印到屏幕和从键盘中提取数据一般使用cout<<和cin>>的方式,但是输入输出流对象函数相应第一个参数分别是ostream和istream的类对象,但是在类中每个函数都规定第一个参数是隐含的this指针作为参数,所以在类中实现便行不通,但是我们进行输出和输入都肯定需要访问类中的成员变量的,而一般的成员变量都是私有或者保护的,所以我们只能使用友元函数的方式,在外部实现流插入操作符和流提取操作符的重载,在类型声明成友元。

这是对流插入的重载我在外面实现在类中进行友元的声明即声明加friend,这样这个函数便能通过对象名字来完成对私有和保护成员的访问了。

友元函数是不受类作用域的限制的,友元函数能在任何地方实现,并通过对象完成对对象内部所有成员的访问,但是友元函数不能使用const修饰。

友元类

友元类与函数的声明相似,以上面类为例,若要将Add这个类声明为其他类的友元类只需要在类的任意地方加上“friend class Add”即可。

声明完之后那么我的Add的所有函数就自动成为这个类的友元函数可以访问这个类的所有成员。友元是单向的Add类可以访问这个类的所有成员但是这个函数并不能访问Add类的私有保护成员。

友元关系不能传递,A是B的友元,B是C的友元并不代表A是C的友元。即朋友的朋友并不是朋友。

友元不能继承,若A是B的友元,C继承B,A也不是C的友元。

内部类

我们可以在一个类内部再定义一个类,这个再定义的类就是内部类。内部类天生是外部类的友元类,但是调用外部类的static成员时并不需要添加类名或者对象名。

外部类对内部类的访问权限是没有改变的,就如一般从外部访问类的对象一样,不可访问私有保护,只能访问公有成员。当我们用sizeof()对外部类计算大小时是不计算内部类的。

类的总结

类是一个抽象的概念,在计算机的世界没有复杂的定义只有二进制,但是人类是可以进行抽象的联想的。所以就有了类,类就如同是人与计算机的一种交流规则,人的抽象思想定义一个类,通过细节的实现完成类被计算机去理解(这里还需要经过编译器的翻译)。这样我们就可以复用这个类而让人与计算机的交流变得更为高效。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值