所有的 C++ 程序都由以下两个基本要素组成:
-
程序语句(代码) — 这是程序执行动作的部分,它们被称为函数。
-
程序数据 — 数据是程序的信息部分,受到程序函数的影响。
封装是面向对象编程的一个概念,它将数据与其用于操纵数据的函数捆绑在一起,并保持两者不受外界干扰和滥用。数据封装导致了重要的面向对象编程概念—数据隐藏。
数据封装是一种捆绑数据及其使用函数的机制,而数据抽象则是只暴露接口并隐藏实现细节的机制。
C++ 通过创建用户定义的类型,即类,来支持封装和数据隐藏的属性。我们已经了解到,一个类可以包含私有、受保护和公共成员。默认情况下,类中定义的所有项都是私有的。例如:
class Box {
public:
double getVolume(void) {
return length * breadth * height;
}
private:
double length;
double breadth;
double height;
};
变量 length
、breadth
和 height
是私有的。这意味着它们只能被 Box
类的其他成员访问,而不能被程序的其他部分访问。这是实现封装的一种方式。
为了让类的一部分公开(即,可被程序的其他部分访问),你必须在 public
关键字之后声明它们。所有在 public
限定符之后定义的变量或函数都可以被程序中的所有其他函数访问。
让一个类成为另一个类的朋友会暴露其实现细节并减少封装。理想情况是尽可能多地隐藏每个类的细节不让其他类知道。
数据封装示例
任何一个你实现了具有公共和私有成员的类的 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
上述类将数字相加,并返回总和。公共成员 addNum
和 getTotal
是对外世界的接口,用户需要知道它们才能使用这个类。私有成员 total
是对外界隐藏的,但它对于类的正常运作是必要的。
设计策略
我们大多数人已经学会了默认将类成员设为私有的,除非我们确实需要暴露它们。这只是良好的封装实践。
这最常应用于数据成员,但它同样适用于所有成员,包括虚函数。