详细分析C++ 数据封装和数据抽象

我们先来了解一下数据封装和数据抽象的概念。

数据封装是指将实现细节隐藏,仅暴露对外接口,归纳如下:

  • 定义私有成员变量来放置数据,避免外界直接访问该变量
  • 定义公有成员函数来访问私有成员变量,对外暴露接口

数据抽象是指将具体实现细节和概念分离,只呈现出必要的接口,归纳如下:

  • 定义抽象类和纯虚函数来实现数据的抽象,将实际的实现交给子类

具体的实现过程如下:

  1. 定义类与访问控制

首先,我们定义一个类,并使用 publicprivate 关键词对成员变量和成员函数进行访问控制。其中 private 成员变量作为数据存储的载体,需要进行保护,无法直接被外界访问;而 public 成员函数允许外部代码与类进行交互,从而实现对封装的数据进行操作。

class Person
{
private:
  string m_name;
  int m_age;

public:
  void setName(string name) { m_name = name; }
  void setAge(int age) { m_age = age; }
  string getName() { return m_name; }
  int getAge() { return m_age; }
};

上述代码中,我们定义了 Person 类,并包含了两个私有成员变量 m_namem_age,分别用于存储人的姓名和年龄。同时,我们定义了四个公有成员函数:

  • setNamesetAge 用于设置私有成员变量值
  • getNamegetAge 用于获取私有成员变量值

这样做的好处是,我们可以避免外部代码直接访问和操作私有成员变量,从而保证了数据的封装性。

  1. 定义抽象类与纯虚函数

接下来,我们将人员抽象为一个接口,并定义一个抽象类 IPerson。我们在其中定义了一个纯虚函数 virtual void display() = 0;,用于展示人员信息。纯虚函数没有实现语句,要求子类继承并实现它,从而将数据的具体实现委托给子类,实现数据的抽象。

class IPerson
{
public:
  virtual void display() = 0;
};

class Student : public IPerson
{
private:
  string m_name;
  int m_age;
  int m_score;

public:
  Student(string name, int age, int score) : m_name(name), m_age(age), m_score(score) {}

  virtual void display()
  {
    cout << "My name is " << m_name << ", I'm " << m_age << " years old, and my score is " << m_score << endl;
  }
};

class Teacher : public IPerson
{
private:
  string m_name;
  int m_age;
  string m_course;

public:
  Teacher(string name, int age, string course) : m_name(name), m_age(age), m_course(course) {}

  virtual void display()
  {
    cout << "My name is " << m_name << ", I'm " << m_age << " years old, and I teach " << m_course << endl;
  }
};

上述代码中,我们定义了 IPerson 类,并包含一个纯虚函数 display,子类必须继承并实现该函数。接着,我们定义了两个子类 StudentTeacher,它们继承自 IPerson 并实现了 display 函数,以展示学生和老师的信息。这样一来,我们可以将具体实现交给子类,从而实现了数据的抽象。

下面是示例代码的完整实现,可以体验一下:

#include <iostream>

using namespace std;

class Person
{
private:
  string m_name;
  int m_age;

public:
  void setName(string name) { m_name = name; }
  void setAge(int age) { m_age = age; }
  string getName() { return m_name; }
  int getAge() { return m_age; }
};

class IPerson
{
public:
  virtual void display() = 0;
};

class Student : public IPerson
{
private:
  string m_name;
  int m_age;
  int m_score;

public:
  Student(string name, int age, int score) : m_name(name), m_age(age), m_score(score) {}

  virtual void display()
  {
    cout << "My name is " << m_name << ", I'm " << m_age << " years old, and my score is " << m_score << endl;
  }
};

class Teacher : public IPerson
{
private:
  string m_name;
  int m_age;
  string m_course;

public:
  Teacher(string name, int age, string course) : m_name(name), m_age(age), m_course(course) {}

  virtual void display()
  {
    cout << "My name is " << m_name << ", I'm " << m_age << " years old, and I teach " << m_course << endl;
  }
};

int main()
{
  // Example 1: Encapsulation
  Person person;
  person.setName("John");
  person.setAge(30);
  cout << "My name is " << person.getName() << ", I'm " << person.getAge() << " years old" << endl;

  // Example 2: Abstraction
  IPerson* student = new Student("Alex", 20, 90);
  student->display();
  IPerson* teacher = new Teacher("Bob", 40, "Math");
  teacher->display();

  return 0;
}

输出结果为:

My name is John, I'm 30 years old
My name is Alex, I'm 20 years old, and my score is 90
My name is Bob, I'm 40 years old, and I teach Math

可以看到,我们成功地封装了学生和老师的数据,同时实现了数据的抽象。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:详细分析C++ 数据封装和数据抽象 - Python技术站

(0)
上一篇 2023年6月25日
下一篇 2023年6月25日

相关文章

  • C语言运算符深入探究优先级与结合性及种类

    C语言运算符深入探究优先级与结合性及种类 1. 优先级与结合性的概念 在C语言中,运算符的优先级和结合性决定了表达式中各个运算符的执行顺序。优先级越高的运算符,越先被执行。结合性则用于解决同一优先级的多个运算符出现时,如何确定运算顺序。 2. 运算符种类及优先级 C语言中的运算符可以分为以下几类,按照优先级从高到低排序: 2.1 一元运算符 一元运算符只有一…

    other 2023年6月28日
    00
  • 关于C++11中限定作用域的枚举类型的问题

    关于C++11中限定作用域的枚举类型的问题 在C++11中,引入了限定作用域的枚举类型(Scoped Enum),它们提供了更好的类型安全性和可读性。本攻略将详细介绍限定作用域的枚举类型的使用方法,并提供两个示例说明。 1. 定义限定作用域的枚举类型 限定作用域的枚举类型使用关键字enum class或enum struct来定义。下面是一个示例: enum…

    other 2023年8月19日
    00
  • Win10系统开机后黑屏需强制关机再重启才能进入系统的故障原因及解决方法

    故障原因分析 出现Win10系统开机后黑屏需强制关机再重启才能进入系统的故障,一般会有以下几种原因: 1. 硬件问题 可能是硬盘、内存、显卡等硬件出现问题,导致系统无法正常启动显示,造成黑屏现象。 解决方法:建议用硬件检测工具进行检测,排查出故障硬件,进行更换或修复。例如使用Memtest86检测内存或使用硬盘检测工具检测硬盘问题。 2. 病毒感染 可能是系…

    other 2023年6月27日
    00
  • KMP算法最浅显理解(小白教程)

    KMP算法最浅显理解(小白教程) 什么是KMP算法? KMP算法(Knuth-Morris-Pratt算法)是一种字符串匹配算法,用于在一个主串中查找一个模式串的出现位置。与朴素的字符串匹配算法相比,KMP算法具有更高的效率。 KMP算法的基本思想 KMP算法的基本思想是利用已经匹配过的部分信息,避免不必要的回溯。它通过构建一个部分匹配表(Partial M…

    other 2023年8月6日
    00
  • adbdevices找不到设备的解决方法

    简介 在使用Android Debug Bridge (ADB)连接Android设备时,有时会出现adb devices找不到设备的情况。在本攻略中,我们将介绍如何解决adb devices找不到设备的问题,并提两个示例说明。 步骤 以下是解决adb devices找不到设备的步骤。 步骤1:检查设备连接 首先,我们需要检查设备是否正确连接到计算机。我们可…

    other 2023年5月6日
    00
  • Android编程自定义菜单实现方法详解

    下面是针对”Android编程自定义菜单实现方法详解”的完整攻略: 1. 导入菜单资源 首先,我们需要在res/menu目录下创建一个XML文件,来编写我们自定义菜单的内容。比如这里我们创建一个custom_menu.xml文件,它的内容如下: <menu xmlns:android="http://schemas.android.com/a…

    other 2023年6月25日
    00
  • vue之项目中如何封装loading加载效果

    在Vue项目中,封装loading加载效果可以提高页面交互体验,用户操作体验更加流畅。 以下是封装loading加载效果的完整攻略: 1. 创建全局Loading组件 我们可以使用Vue的全局组件来封装loading效果。首先,创建一个loading组件,例如: <template> <div class="loading-mas…

    other 2023年6月25日
    00
  • uni-app分包项目实战总结

    uni-app分包项目实战总结 什么是uni-app分包 uni-app分包是指将一个uni-app项目中的代码按照一定的规则拆分成多个子包,让应用在运行时可以动态的加载子包代码,从而实现分包存储和加载,优化应用的启动速度和减少应用的总包大小。 如何分包 步骤一:配置子包 在uni-app项目中,使用分包需要在manifest.json文件中配置各个子包的相…

    other 2023年6月27日
    00
合作推广
合作推广
分享本页
返回顶部