最近这段时间,我们学习了类这部分的内容,学完了这一章,我们也是上交了这学期的第一次作业,可以说这次作业让我看到了自己在知识掌握运用方面的不足。接下来,我梳理一下本章所学的知识点,可以对我掌握知识有所帮助。
一.类的定义
类的基本思想是数据抽象和封装。数据抽象是一种依赖接口和实现分离编程的技术。类的接口包括用户能执行的操作,实现则包括类的数据成员、负责接口实现的函数体以及定义类所需的各种私有函数。实现数据抽象和封装,需要定义抽象数据类型。
※抽象数据类型:由两部分组成,数据和对这些数据的操作。操作向程序的其余部分展现了这些数据是怎样的,程序的其余部分则通过操作改变这些数据。
※数据成员与成员函数:结构体内的函数成为成员函数,结构体中的数据称为数据成员,这样的结构体称为类,这种结构体类型的变量称为对象(如 struct x{…};int main(){x s;…}。 则s为结构体x类型的变量,也称对象)
※数据成员类内初始化:初始值只能放在"=“右侧,或者放在”{}",不能用圆括号。
※成员函数类外定义:即在类内写成员函数声明,在类外写函数体。成员函数在类外定义时,函数名字前面要加类名字和作用域符"::",表示这个函数是在其所属的类作用域内,是这个类的成员函数,不同于全局函数。注意,在类定义花括号内定义的成员函数默认为inline函数,而若要在类外定义inline成员函数,则需要显式地在函数声明或定义前加关键字inline。
※类代码的组织:在组织类代码时,一个类的定义通常分为两个文件:类及其成员的声明放在头文件中,而将成员函数的类外定义放在源文件中,并在其中包含头文件。注意,类成员的声明不能分割在不同的文件中。类定义的头文件和类实现的源文件一般使用相同的名字,在使用类的客户程序中只需要包含头文件就可以。
※包含守卫:类定义的头文件不能被重复包含,不然会引起编译错误,为避免这类错误,我们需要用到包含守卫。
格式:
#ifndef HEADER_FLAG
#define HEADER_FLAG
//类型定义
#endif
为避免标记冲突,HEADER_FLAG通常用头文件的名字。这样的头文件第一次被包含时,其类型定义会被预处理器包含在被编译的源文件中,对于同一源文件中的后续其他包含,这个类型定义将被忽略。
二.访问控制和封装
※访问限定符:关键字public、private被称为访问限定符。在类定义中使用,语法如下:
Struct类名{
public:
公有成员声明;
private:
私有成员声明;
};
一个访问限定符的作用会持续到出现下一个访问限定符或类定义结束。如果没有指定访问限定符,struct成员的默认访问限制为public。
public成员在程序的任何函数或类中都可以被访问。
Private成员只能由类自己的成员函数或友元访问。
※类和对象
将数据和操作捆绑在一起,并加上访问控制,这在面向对象中成为封装。对象是数据和操作的封装体;数据描述对象的属性,操作描述对象的行为。对象又称类的实例。
关键字class:跟struct大致相同功能,略有不同。不同:class成员如果没有设置访问限定符,则默认为private,但相同情况下struct成员的默认访问限定是public。
※this指针:每个成员函数都有一个隐含的参数,指向接受消息的对象,称this指针。this指针是一个常量,含有当前实施调用对象的地址。不能改变this指针的值,也不能取this指针的地址。
※友元:friend关键字,如果想让非成员函数访问一个类中的私有数据,应该在类中将这个函数声明为friend(友元)。在声明友元时要遵循一条规则:友元必须在被访问的类中声明。注意,friend关系是不可传递的。
三.构造函数和析构函数
※构造函数:是一种特殊的成员函数,在创建对象时自动被调用,负责对象的初始化,名字跟类名字相同,没有返回类型,注意不是void类型。构造函数的参数通常为数据成员提供初值。构造函数可以重载。注意,一个类的构造函数至少要有两个,一个有参数,一个没有参数。
※构造函数初始化列表:初始化由构造函数完成,引用成员的初始化也应该在构造函数中,但是又不能在函数体中使用赋值方式提供初值。针对这一情况的的特殊语法叫做构造函数初始化列表。
形式:成员1(初始值1),成员2(初始值2)
位置:构造函数后,用":“隔开。函数体之前。
※委托构造函数:一个构造函数可以调用另一个构造函数来完成自己的部分或全部初始化过程。委托构造函数有一个成员初始化列表和一个函数体。成员初始化列表只有唯一一项,即类名本身。类名后面紧跟圆括号括起来的参数列表,参数列表必须与类中另一个构造函数匹配。
※析构函数:由析构函数负责在对象生存期结束时返回相关资源和自动释放资源。当对象离开作用域时,或者用delete释放在堆上创建的对象时,析构函数都会被自动调用。析构函数的名字是类名字前加波浪线”~",析构函数没有返回类型,也没有任何参数,不能重载,只能为一个类定义唯一的一个析构函数。注意,如果一个类只包含按值存储的数据成员,则析构函数不是必须定义的。如果类中没有定义析构函数,编译器在需要时会自动合成一个析构函数。
四.const成员
※const数据成员:在数据成员声明前加const关键字就将其限定为常量。const数据成员在构造函数的初始化列表中初始化。创建对象时初始化其中的const数据成员,之后const成员的值在对象的整个生存期中都不会改变。
※const成员函数:
语法形式:返回类型 成员函数名 (参数列表 )const {函数体}
Const成员函数声明:返回类型 成员函数名 (参数表) const;
五.static成员
※static数据成员:静态数据成员。被当做类类型内部的全局变量。对非静态数据成员,每个对象都有自己的副本,②静态数据成员在整个类中只有一份,由这个类所有对象共享访问。static数据成员在类定义之外初始化。在定义时要使用类名字限定静态成员名,但不需要重复出现static关键字。
现在的我当真发现这门学科的困难所在,也领略了它的魅力,让人痛并快乐着,学会时的成就感自己做不出来时的急迫,既然决定学习c++,就要一直坚持到最后,今后的学习要按部就班,多积累,多作用。