类的封装在于操作数据的函数附属于数据及数据的访问控制。
封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据封装引申出了另一个重要的 OOP 概念,即数据隐藏。数据隐藏通过访问权限控制符来定义。
数据封装是一种把数据和操作数据的函数捆绑在一起的机制,数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制。
C++ 通过创建类来支持封装和数据隐藏。类的访问控制符定义成员时分为三类:私有成员(private)、保护成员(protected)和公有成员(public)成员。默认情况下,在类中定义的所有项目都是私有的。例如:
class Box{ public: double getVolume(void) { return length * breadth * height; } private: double length; // 长度 double breadth; // 宽度 double height; // 高度};
变量 length、breadth 和 height 都是私有的(private)。这意味着它们只能被 Box 类中的其他成员访问,而不能被程序中其他部分访问。这是实现封装的一种方式。
为了使类中的成员变成公有的(即,程序中的其他部分也能访问),必须在这些成员前使用 public 关键字进行声明。所有定义在 public 标识符后边的变量或函数可以被程序中所有其他的函数访问。
私有成员(private):只能由类的成员函数调用;
公有成员(public):外界可以调用的信息,是类对外的接口;
私有成员被封装在一个类中,外界是看不见的;
从以上的封装可见,数据成员和操作这些数据成员的函数形成了一个有效的整体(还有类域操作符号::访问限制的概念)。相对于面向过程的以函数为模块单元,函数和局部变量、全局变量、参数的结合没有类内成员的结合那么紧密。再加上访问权限的控制,面向对象的类机制,能够更好地实现接口、黑盒隐藏,接口实现的分离机制:
#include using namespace std;class Adder{public:// 构造函数Adder(int i = 0){total = i;}// 对外的接口void addNum(int number){total += number;}// 对外的接口int getTotal(){return total;};private:// 对外隐藏的数据int total;};int main( ){Adder a;a.addNum(10);a.addNum(20);a.addNum(30);cout << "Total " << a.getTotal() <
上面的类把数字相加,并返回总和。公有成员 addNum 和 getTotal 是对外的接口,用户需要知道它们以便使用类。私有成员 total 是对外隐藏的,用户不需要了解它,但它又是类能正常工作所必需的。
通常情况下,我们都会设置类成员状态为私有(private),除非我们真的需要将其暴露,这样才能保证良好的封装性。
当然,凡事都不能绝对,当特殊情况下需要允许外部函数访问private数据成员时,可以声明为外部函数为类的友元。
把一个类定义为另一个类的友元类,会暴露实现细节,从而降低了封装性。理想的做法是尽可能地对外隐藏每个类的实现细节。
在继承关系中,可以声明基类的protected访问属性,外部函数只有派生类的成员函数可以访问,当然友元也是可以访问的。
![6baec17b231d219502df2e28e463d4a2.png](https://i-blog.csdnimg.cn/blog_migrate/61feb879482ea1e2f3b7a440b2e59ec1.jpeg)
-End-