Cplusplus 简明教程

Data Abstraction in C++

数据抽象是指只向外界提供基本信息并隐藏其背景细节,即在程序中表示必要的信息而不显示细节。

Data abstraction refers to providing only essential information to the outside world and hiding their background details, i.e., to represent the needed information in program without presenting the details.

数据抽象是一种编程(和设计)技术,它依赖于接口和实现的分离。

Data abstraction is a programming (and design) technique that relies on the separation of interface and implementation.

让我们举一个电视机的真实例子,您可以打开和关闭它,改变频道,调节音量,并添加外部组件,例如扬声器、录像机和 DVD 播放器,但是您不知道它的内部细节,即,您不知道它是如何通过空中或电缆接收信号,如何转换信号以及最后如何将它们显示在屏幕上。

Let’s take one real life example of a TV, which you can turn on and off, change the channel, adjust the volume, and add external components such as speakers, VCRs, and DVD players, BUT you do not know its internal details, that is, you do not know how it receives signals over the air or through a cable, how it translates them, and finally displays them on the screen.

因此,我们可以说电视机清楚地将它的内部实现与其外部接口分开,您可以在不了解其内部知识的情况下使用其接口,如电源按钮、频道转换器和音量控制。

Thus, we can say a television clearly separates its internal implementation from its external interface and you can play with its interfaces like the power button, channel changer, and volume control without having any knowledge of its internals.

在 C++ 中,类提供了很高的 data abstraction 级别。它们向外界提供了足够多的公共方法,以使用对象的函数并操作对象数据(即状态),而无需实际了解该类在内部是如何实现的。

In C++, classes provides great level of data abstraction. They provide sufficient public methods to the outside world to play with the functionality of the object and to manipulate object data, i.e., state without actually knowing how class has been implemented internally.

例如,您的程序可以调用 sort() 函数,而不知道函数实际使用什么算法来对给定值进行排序。事实上,排序功能的基础实现可以在库的发布之间更改,并且只要接口保持不变,您的函数调用仍然有效。

For example, your program can make a call to the sort() function without knowing what algorithm the function actually uses to sort the given values. In fact, the underlying implementation of the sorting functionality could change between releases of the library, and as long as the interface stays the same, your function call will still work.

在 C++ 中,我们使用 classes 来定义我们自己的抽象数据类型 (ADT)。你可以使用类 ostreamcout 对象以这种方式将数据流式传输到标准输出:

In C++, we use classes to define our own abstract data types (ADT). You can use the cout object of class ostream to stream data to standard output like this −

#include <iostream>
using namespace std;

int main() {
   cout << "Hello C++" <<endl;
   return 0;
}

在这里,无需了解 cout 如何在用户的屏幕上显示文本。你只需要了解公用接口,并且 ‘cout’ 的底层实现是免费更改的。

Here, you don’t need to understand how cout displays the text on the user’s screen. You need to only know the public interface and the underlying implementation of ‘cout’ is free to change.

Access Labels Enforce Abstraction

在 C++ 中,我们使用访问标签来定义类的抽象接口。一个类可能含有零个或多个访问标签:

In C++, we use access labels to define the abstract interface to the class. A class may contain zero or more access labels −

  1. Members defined with a public label are accessible to all parts of the program. The data-abstraction view of a type is defined by its public members.

  2. Members defined with a private label are not accessible to code that uses the class. The private sections hide the implementation from code that uses the type.

访问标签可以出现多次,对此没有限制。每个访问标签指定了后续成员定义的访问级别。指定访问级别有效,直到遇到下一个访问标签或看到类体的闭合右大括号。

There are no restrictions on how often an access label may appear. Each access label specifies the access level of the succeeding member definitions. The specified access level remains in effect until the next access label is encountered or the closing right brace of the class body is seen.

Benefits of Data Abstraction

数据抽象提供了两个重要优势:

Data abstraction provides two important advantages −

  1. Class internals are protected from inadvertent user-level errors, which might corrupt the state of the object.

  2. The class implementation may evolve over time in response to changing requirements or bug reports without requiring change in user-level code.

通过仅在类的私有部分中定义数据成员,类作者可以自由地更改数据。如果实现发生变化,只须检查类代码即可查看更改可能会产生什么影响。如果数据是公开的,则任何直接访问旧表示形式的数据成员的函数都可能损坏。

By defining data members only in the private section of the class, the class author is free to make changes in the data. If the implementation changes, only the class code needs to be examined to see what affect the change may have. If data is public, then any function that directly access the data members of the old representation might be broken.

Data Abstraction Example

任何实现具有公有和私有成员的类的 C++ 程序都是数据抽象的一个例子。考虑以下示例:

Any C++ program where you implement a class with public and private members is an example of data abstraction. Consider the following example −

#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;
}

编译并执行上述代码后,将产生以下结果 −

When the above code is compiled and executed, it produces the following result −

Total 60

上述类将数字相加,并返回总和。公有成员 addNumgetTotal 是与外界的接口,用户需要了解它们才能使用该类。私有成员 total 是用户不需要了解的,但类需要它才能正常运行。

Above class adds numbers together, and returns the sum. The public members - addNum and getTotal are the interfaces to the outside world and a user needs to know them to use the class. The private member total is something that the user doesn’t need to know about, but is needed for the class to operate properly.

Designing Strategy

抽象将代码划分为接口和实现。因此,在设计组件时,你必须保持接口独立于实现,以便在更改底层实现时,接口保持不变。

Abstraction separates code into interface and implementation. So while designing your component, you must keep interface independent of the implementation so that if you change underlying implementation then interface would remain intact.

在这种情况下,无论哪些程序使用这些接口,都不会受到影响,只需使用最新的实现重新编译即可。

In this case whatever programs are using these interfaces, they would not be impacted and would just need a recompilation with the latest implementation.