我们已经为类定义了接口,但是并没有任何机制强制用户使用这些接口。
类还没有封装,也就是说用户可以直达 sales_data 对象的内部并且控制它的具体实现细节。
在 C++ 中,使用访问说明符加强类的封装性。
定义在 public 说明符之后的成员在整个程序内可被访问,public 成员定义类的接口。
定义在 private 说明符之后的成员可以被类的成员函数访问,但是不能被使用该类的代码访问,private 部分封装了类的实现细节。
作为接口的一部分,构造函数和部分成员函数紧跟在 public 说明符后,数据成员和作为实现部分的函数则跟在 private 说明符后。
一个类可以包含 0 或 多个 访问说明符,而且对于某个访问说明符能出现多少次也没有严格限定。
每个访问说明符指定了接下来的成员的访问级别,其有效范围直到出现下一个访问说明符或到达类的结尾。
上述定义中,使用的是 class 而非 struct 开始类的定义。仅仅是形式上有所不同,实际上我们可以使用这两个关键字中的任何一个定义类。区别仅是 struct 和 class 的默认访问权限不太一样。
类可以在它的第一个访问说明符之前定义成员,对这种成员的访问权限依赖于类定义的方式。若使用 struct 则定义在第一个访问说明符之前的成员是 public ;若使用 class 则这些成员是 privat 。
既然 sales_data 的数据成员是 private 的,我们的 read、print、add 函数也就无法正常编译了,这是因为尽管这几个函数是类的接口的一部分,但不是类的成员。
类可以允许其它类或者函数访问它的非公有成员,方法是令其它类或者函数称为它的友元。
如果类想把一个函数作为它的友元,只要增加一条以 friend 关键字开始的函数声明语句即可。
友元声明只能出现在类定义的内部,但是类内出现的具体位置不限。
友元不是类的成员也不受它所在区域访问控制级别的约束。
封装有两个重要的有点:
确保用户代码不会无意间破坏封装对象的状态。
被封装的类的具体实现细节可以随时改变,而无须调整用户级别的代码。
友元的声明仅仅制定了访问权限,而非一个通常意义上的函数声明。若希望类的用户能够调用某个友元函数,那么我们就必须在友元声明之外再专门对函数进行一次声明。
为了使友元对类的用户可见,我们通常把友元的声明与类本身放置在同一个头文件中(类的外部)