类的基本思想是数据抽象和封装
7.1定义抽象数据类型
定义在类内部的函数是隐式的inline函数
成员函数体可以在类内也可以在类外
定义类
使用类
Sales_data的成员
定义成员函数
引入this
this 是一个常量指针,不可改变this中保存的地址
引入const成员函数
C++中的 struct 和 class 基本是通用的,唯有几个细节不同:
1:使用 class 时,类中的成员默认都是 private 属性的;而使用 struct 时,结构体中的成员默认都是 public 属性的。(最本质的区别)
2:class 继承默认是 private 继承,而 struct 继承默认是 public 继承(《C++继承与派生》一章会讲解继承)。
3:class 可以使用模板,而 struct 不能。
7.1.4构造函数
名字和类名相同,没有返回类型,不能被声明成const的
默认构造函数:无需实参
只有当类没有声明任何构造函数时,编译器才会自动的生成默认构造函数
7.1.5拷贝、赋值、析构
7.2访问控制与封装
封装实现了类的接口和实现的分离,隐藏了类的实现细节,用户只能接触到类的接口。
优点:
隐藏类的实现细节;
让使用者只能通过程序规定的方法来访问数据;
可以方便的加入存取控制语句,限制不合理操作;
类自身的安全性提升,只能被访问不能被修改;
类的细节可以随时改变,不需要修改用户级别的代码;
7.2.1友元
友元在类内,具体位置不限
友元的声明用于指定访问权限
7.3类的其他特性
7.3.3类类型
即使类内成员完全一样,两个类也是两个不同的类型
类允许包含指向它自身类型
7.3.4友元再探
友元类的成员可以访问此类的所有成员
令成员函数作为友元:明确指出该成员所属类,如:
friend void window_mgr::clear();
类和非成员函数的声明不是必须在它们的友元声明之前。
7.4类的作用域
知识点1:名字查找的顺序:由内而外、自上而下
知识点2:类的定义处理步骤:首先编译成员的声明,直到类全部可见是再编译函数体
即成员函数在类的声明全部处理完之后才会被定义,所以可以调用函数中定义的任何名字
知识点3:在类中,类型名要特殊处理,最好是定义在类的一开始,并且不能与外层作用域中同名
7.5构造函数再探
7.5.1初始值列表
-
如果没有在构造函数的初始值列表中显式的初始化成员,则该成员将在构造函数体之前进行默认初始化
-
构造函数初始值列表中的初始值顺序不会影响实际的初始化顺序
-
知识点1:类内成员是const、引用时或者使用某种类类型没有默认构造函数的成员时必须将其初始化
知识点2:初始化和赋值是不等价的
知识点3:成员初始化的顺序一般是没有要求的,但是若用一个成员来初始化另一个成员是,就必须考虑到其定义时的顺序(写时保持顺序一直即可)
7.5.2委托构造函数
使用它所属类的其他构造函数执行它自己的初始化过程,即它把它自己的一些职责委托给了其他构造函数
当构造函数委托给另一个构造函数时,受委托的构造函数的初始值列表及其函数体先被执行,接着才会执行到委托函数的函数体。
class OH{
OH(string s, int a, int b):book(s),price(a),sale(b){} //三参数构造函数的参数列表和函数体首先被执行
OH():OH("",0,0);//默认构造函数又委托给了三参数构造函数
OH (istream& is):OH(){}//OH (istream& is)是一个委托构造函数,它委托给了默认构造函数OH()
string book;
int price;
int sale;
};
7.5.3默认构造函数的作用
知识点1:默认构造函数在很多情况下也是非常重要的。
1:当类的作用域内不需要使用任何初始值定义非静态变量时
2:当类中含有需要使用默认构造函数当作被委托构造函数时
3:类的成员没有在构造函数初始值列表中显示初始化时
知识点2:当类中定义了其它类型的构造函数时,最好提供一个默认的构造函数,养成良好的习惯。
知识点3:类声明对象是不需要加括号!加括号是声明函数的。
7.5.4隐式的类类型转换
抑制构造函数定义的隐式转换
将构造函数声明用explicit加以阻止
关键字explicit只对一个实参的构造函数有效
explicit只能在类内使用
explicit构造函数只能用于直接初始化
7.5.5聚合类
聚合类的条件:
1.所有成员都是public的
2.没有定义任何构造函数
3.没有类内初始值
4.没有基类,没有virtual函数
7.5.6字面值常量类
数据成员都是字面值类型的聚合类是字面值常量类
类至少含有一个constexpr构造函数
7.6类的静态成员
知识点1:类的静态成员:该成员只需与类的本身有关,而不是与类的对象有关,加上static关键字即可声明,其不与任何实例化对象绑定,但是我们仍然可以使用类作用域运算符访问静态成员。
知识点2:static声明在内部。在外部定义时,不加static.类似与一个全局变量,其初始值必须是常量表达式。
知识点3:静态成员独立于任何对象,其类型可以是它所属的类类型。而非静态成员只能声明为其类的指针或引用
类外定义静态成员时不能重复static关键字
静态成员的类内初始化