Cplusplus 简明教程
Data Abstraction in C++
数据抽象是指只向外界提供基本信息并隐藏其背景细节,即在程序中表示必要的信息而不显示细节。
数据抽象是一种编程(和设计)技术,它依赖于接口和实现的分离。
让我们举一个电视机的真实例子,您可以打开和关闭它,改变频道,调节音量,并添加外部组件,例如扬声器、录像机和 DVD 播放器,但是您不知道它的内部细节,即,您不知道它是如何通过空中或电缆接收信号,如何转换信号以及最后如何将它们显示在屏幕上。
因此,我们可以说电视机清楚地将它的内部实现与其外部接口分开,您可以在不了解其内部知识的情况下使用其接口,如电源按钮、频道转换器和音量控制。
在 C++ 中,类提供了很高的 data abstraction 级别。它们向外界提供了足够多的公共方法,以使用对象的函数并操作对象数据(即状态),而无需实际了解该类在内部是如何实现的。
例如,您的程序可以调用 sort() 函数,而不知道函数实际使用什么算法来对给定值进行排序。事实上,排序功能的基础实现可以在库的发布之间更改,并且只要接口保持不变,您的函数调用仍然有效。
在 C++ 中,我们使用 classes 来定义我们自己的抽象数据类型 (ADT)。你可以使用类 ostream 的 cout 对象以这种方式将数据流式传输到标准输出:
#include <iostream>
using namespace std;
int main() {
cout << "Hello C++" <<endl;
return 0;
}
在这里,无需了解 cout 如何在用户的屏幕上显示文本。你只需要了解公用接口,并且 ‘cout’ 的底层实现是免费更改的。
Access Labels Enforce Abstraction
在 C++ 中,我们使用访问标签来定义类的抽象接口。一个类可能含有零个或多个访问标签:
-
使用公用标签定义的成员在程序的所有部分都可以访问。类型的抽象数据视图是由其公用成员定义的。
-
使用私有标签定义的成员对于使用该类的代码是不可访问的。私有部分将实现隐藏在使用该类型代码中。
访问标签可以出现多次,对此没有限制。每个访问标签指定了后续成员定义的访问级别。指定访问级别有效,直到遇到下一个访问标签或看到类体的闭合右大括号。
Benefits of Data Abstraction
数据抽象提供了两个重要优势:
-
类内部不受无意的用户级错误的影响,而这些错误可能会损坏对象的状况。
-
随着变化需求或错误报告的出现,类实现会随着时间的推移发展,而不需要更改用户级代码。
通过仅在类的私有部分中定义数据成员,类作者可以自由地更改数据。如果实现发生变化,只须检查类代码即可查看更改可能会产生什么影响。如果数据是公开的,则任何直接访问旧表示形式的数据成员的函数都可能损坏。
Data Abstraction Example
任何实现具有公有和私有成员的类的 C++ 程序都是数据抽象的一个例子。考虑以下示例:
#include <iostream>
using namespace std;
class Adder {
public:
// constructor
Adder(int i = 0) {
total = i;
}
// interface to outside world
void addNum(int number) {
total += number;
}
// interface to outside world
int getTotal() {
return total;
};
private:
// hidden data from outside world
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 是用户不需要了解的,但类需要它才能正常运行。