C++ 中的数据封装
所有 C++ 程序都由以下两个基本元素组成 −
程序语句(代码) − 这是程序中执行操作的部分,它们被称为 functions。
程序数据 − 数据是程序的信息,会受到程序 functions 的影响。
Encapsulation 是面向对象编程(Object Oriented Programming)的一个概念,它将数据及其操作数据的 functions 绑定在一起,并保护它们免受外部干扰和滥用。数据封装导致了重要的 OOP 概念 数据隐藏(data hiding)。
数据封装 是将数据及其使用这些数据的 functions 捆绑在一起的一种机制,而 数据抽象(data abstraction)是一种只暴露接口并向用户隐藏实现细节的机制。
C++ 通过创建用户定义类型,即 classes,来支持 encapsulation 和数据隐藏的特性。我们已经学习过,一个 class 可以包含 private、protected 和 public 成员。默认情况下,class 中定义的所有成员都是 private。例如 −
class Box {
public:
double getVolume(void) {
return length * breadth * height;
}
private:
double length; // 盒子的长度
double breadth; // 盒子的宽度
double height; // 盒子的高度
};
变量 length、breadth 和 height 是 private 的。这意味着它们只能被 Box class 的其他成员访问,而不能被程序的其他部分访问。这是实现 encapsulation 的一种方式。
要使 class 的某些部分成为 public(即可被程序的其他部分访问),必须在 public 关键字之后声明它们。public 说明符之后定义的所有变量或 functions 都可以被程序中的所有其他 functions 访问。
将一个 class 声明为另一个 class 的 friend 会暴露实现细节并降低封装。理想情况下,应尽可能将每个 class 的细节对其他所有 class 隐藏。
数据封装示例
任何实现带有 public 和 private 成员的 class 的 C++ 程序,都是数据封装和数据抽象的示例。考虑以下示例 −
#include <iostream>
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() <<endl;
return 0;
}
当上述代码编译并执行时,会产生以下结果 −
Total 60
上述 class 将数字相加并返回总和。public 成员 addNum 和 getTotal 是对外界接口,用户需要了解它们才能使用该 class。私有的成员 total 是对外界隐藏的,但 class 正常运行需要它。
设计策略
我们大多数人都学会了默认将 class 成员设为 private,除非真的需要暴露它们。这就是良好的 encapsulation。
这最常应用于数据成员,但同样适用于所有成员,包括 virtual functions。