C++ data abstraction


Data abstraction refers to providing only key information to the outside world and hiding its background implementation details, that is, only showing necessary information without presenting details.

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

Let's take a real life example, say a television, you can turn it on and off, switch channels, adjust the volume, add external components (like speakers, VCR, DVD player), but You don't know its internal implementation details, that is, you don't know how it receives the signal through the cable, converts the signal, and finally displays it on the screen.

Therefore, we can say that the TV separates its internal implementation and external interface. You do not need to know its internal implementation principle, and can directly use its external interface (such as power button, remote control, volume controller) ) to control the TV.

Now, let's get down to business. As far as C++ programming is concerned, C++ classes provide the possibility for data abstraction. They provide a large number of public methods for manipulating object data to the outside world, that is to say, the outside world does not actually know the internal implementation of the class.

For example, your program can call the sort() function without knowing the algorithm used to sort the data in the function. In fact, the underlying implementation of function sorting will vary depending on the version of the library. As long as the interface remains unchanged, function calls will work as usual.

In C++, we use classes to define our own abstract data types (ADT). You can use a cout object of class ostream to output data to standard output as follows:

#include <iostream>
using namespace std;

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

Here, you don’t need to understand cout is how text is displayed on the user's screen. You only need to know the public interface, the underlying implementation of cout can be changed freely.

Access tags force abstraction

In C++, we use access tags to define the abstract interface of a class. A class can contain zero or more access labels:

  • Members defined with public labels have access to all parts of the program. A type's abstract view of data is defined by its public members.

  • Members defined using private tags cannot access the code using the class. The private part hides implementation details from code that uses the type.

There is no limit on the frequency of access tags. Each access tag specifies the access level of the member definition that follows it. The specified access level remains in effect until the next access tag is encountered or the closing closing bracket of the class body is encountered.

Benefits of Data Abstraction

Data abstraction has two important advantages:

  • The internals of the class are protected from inadvertent user-level Errors cause object state to be corrupted.

  • Class implementations may change over time in response to changing requirements or in response to bug reports that require no changes to user-level code.

If you define data members only in the private part of a class, the author of the class can change the data at will. If the implementation changes, you only need to check the code of the class to see what impact this change will have. If the data is public, any function that directly accesses a data member of the old representation may be affected.

Instances of data abstraction

In a C++ program, any class with public and private members can be used as an instance of data abstraction. See the following example:

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

When the above code is compiled and executed, it produces the following results:

Total 60

The above class adds numbers and returns the sum. Public members addNum and getTotal are external interfaces, and users need to know them in order to use the class. Private members total are things that users don’t need to know about, but are necessary for the class to work properly.

Design Strategy

Abstraction separates code into interfaces and implementations. So when designing components, you must keep the interface independent of the implementation, so that if the underlying implementation is changed, the interface will remain unchanged.

In this case, no matter which program uses the interface, the interface will not be affected, and only the latest implementation needs to be recompiled.