C++ 封装怎么实现?类成员访问权限和数据隐藏怎么设置?

文章导读
Previous Quiz Next 所有 C++ 程序都由以下两个基本元素组成 −
📋 目录
  1. A 数据封装示例
  2. B 设计策略
A A

C++ 中的数据封装



Previous
Quiz
Next

所有 C++ 程序都由以下两个基本元素组成 −

  • 程序语句(代码) − 这是程序中执行操作的部分,它们被称为 functions。

  • 程序数据 − 数据是程序的信息,会受到程序 functions 的影响。

Encapsulation 是面向对象编程(Object Oriented Programming)的一个概念,它将数据及其操作数据的 functions 绑定在一起,并保护它们免受外部干扰和滥用。数据封装导致了重要的 OOP 概念 数据隐藏(data hiding)。

数据封装 是将数据及其使用这些数据的 functions 捆绑在一起的一种机制,而 数据抽象(data abstraction)是一种只暴露接口并向用户隐藏实现细节的机制。

C++ 通过创建用户定义类型,即 classes,来支持 encapsulation 和数据隐藏的特性。我们已经学习过,一个 class 可以包含 private、protectedpublic 成员。默认情况下,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 成员 addNumgetTotal 是对外界接口,用户需要了解它们才能使用该 class。私有的成员 total 是对外界隐藏的,但 class 正常运行需要它。

设计策略

我们大多数人都学会了默认将 class 成员设为 private,除非真的需要暴露它们。这就是良好的 encapsulation

这最常应用于数据成员,但同样适用于所有成员,包括 virtual functions。