服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C++多态的示例详解

C++多态的示例详解

2023-02-15 16:09叶落秋白 C/C++

多态按字面的意思就是多种形态。当类之间存在层次结构,并且类之间是通过继承关联时,就会用到多态。本文将通过三个小案例让大家更深入的了解一下C++的多态,感兴趣的可以了解一下

今天就以三个案例来把C++多态的内容结束。第一个案例就是用多态写一个计算器并实现简单的加减乘除操作;第二个案例就是一个饮品制作,主要就是抽象类重写方法;第三个是比较综合的电脑组装案例,正文会详细介绍;那么就开始上手操作吧!

 

案例一:计算器

案例要求

使用多态实现计算器的加减乘除操作

代码实现

class AbstractCalculator
{
public:
  //纯虚函数,用来得到计算结果
  virtual void getResult() = 0;
  float num1, num2;
};
//加法类
class Add :public AbstractCalculator
{
public:
  void getResult()
  {
      cout << num1 << "+" << num2 << "=" << num1 + num2 << endl;
  }
};
//减法类
class Sub :public AbstractCalculator
{
public:
  void getResult()
  {
      cout << num1 << "-" << num2 << "=" << num1 - num2 << endl;
  }
};
//乘法类
class Mul :public AbstractCalculator
{
public:
  void getResult()
  {
      cout << num1 << "*" << num2 << "=" << num1 * num2 << endl;
  }
};
//除法类
class Des :public AbstractCalculator
{
public:
  void getResult()
  {
      cout << num1 << "/" << num2 << "=" << num1 / num2 << endl;
  }
};
void main()
{
  //1、加法
  AbstractCalculator *abc = new Add();
  abc->num1 = 2.1;
  abc->num2 = 3.9;
  abc->getResult();
  delete abc;
  //2、减法
  abc = new Sub();
  abc->num1 = 3.9;
  abc->num2 = 2.1;
  abc->getResult();
  delete abc;
  //3、乘法
  abc = new Mul();
  abc->num1 = 4.2;
  abc->num2 = 2;
  abc->getResult();
  delete abc;
  //4、除法
  abc = new Des();
  abc->num1 = 8.8;
  abc->num2 = 2;
  abc->getResult();
  delete abc;
}

代码解释

首先创建AbstractCalculator类作为基类,设置两个浮点型属性用来做基本运算,并含有纯虚函数getResult。我们知道还有纯虚函数的类被称为抽象类,特点是无法实例化,非抽象子类必须重写抽象类的所有纯虚函数,因此基本运算的类都要重写getResult方法。接下来写了加减乘除四个派生类继承该抽象类,分别给派生类的getResult进行重写,得到不同的计算结果。主函数中利用父类指针来创建子类对象,给两个操作数赋值后调用getResult方法,然后利用delete删除指针。注意删除指针只是删除了那一块地址,该指针的类型是不变的,还可以多次利用,指向不同的子类对象。

运行效果

C++多态的示例详解

 

案例二:制作饮品

案例要求

给出制作饮品的过程为四步:把水煮开、冲泡、倒入杯中、加入佐料。

利用多态写出两个饮品的制作过程

代码实现

#include<iostream>
using namespace std;
//使用多态制作奶茶
class AbstractDrink
{
public:
  //制作开水
  virtual void boiledWater() = 0;
  //冲泡
  virtual void brew() = 0;
  //倒入杯中
  virtual void inCup() = 0;
  //加入佐料
  virtual void pour() = 0;
  void makeDrink()
  {
      this->boiledWater();
      this->brew();
      this->inCup();
      this->pour();
  }
};
//制作咖啡
class Coffee :public AbstractDrink
{
public:
  //煮水
  virtual void boiledWater()
  {
      cout << "先把水煮开" << endl;
  }
  //冲泡 
  virtual void brew()
  {
      cout << "开始冲泡咖啡" << endl;
  }
  //倒入杯中
  virtual void inCup()
  {
      cout << "全部倒入杯中" << endl;
  }
  //加入辅料
  virtual void pour()
  {
      cout << "加入糖和牛奶" << endl;
      cout << "牛奶咖啡制作完成" << endl;
  }
};
//制作茶水
class Tea :public AbstractDrink
{
public:
  //煮水
  virtual void boiledWater()
  {
      cout << "先把水煮开" << endl;
  }
  //冲泡 
  virtual void brew()
  {
      cout << "开始冲泡茶叶" << endl;
  }
  //倒入杯中
  virtual void inCup()
  {
      cout << "全部倒入杯中" << endl;
  }
  //加入辅料
  virtual void pour()
  {
      cout << "加入枸杞" << endl;
      cout << "茶水制作完成" << endl;
  }
};
//制作函数
void DoWork(AbstractDrink* abs)//父类指针指向子类对象AbstractDrinking* abs = new Coffee;
{
  abs->makeDrink();
  delete abs;//手动释放
  //堆区的数据被销毁了但是指针的类型没变,可以多次利用
}
void test()
{
  DoWork(new Coffee);
  cout << "---------------------" << endl;
  DoWork(new Tea);
}
void main()
{
  test();
}

代码解释

这个案例就是直接给一个类中加四个纯虚函数,然后再加一个makeDrink方法来调用全部函数。子类中需要重写四个纯虚函数,制作咖啡和茶的类步骤基本一样。在DoWork函数的形参列表,使用父类的指针,那么在test函数调用DoWork函数就可以直接new子类对象,这样也是父类指针指向子类对象,然后调用makeDrink方法后,用delete删除堆区父类指针,以免内存泄漏。

运行效果

C++多态的示例详解

 

案例三:电脑组装

案例要求

电脑主要组成部件为 CPU(用于计算),显卡(用于显示),内存条(用于存储)

将每个零件封装出抽象基类,并且提供不同的厂商生产不同的零件,例如Intel厂商和Lenovo厂商

创建电脑类提供让电脑工作的函数,并且调用每个零件工作的接口

测试时组装三台不同的电脑进行工作

代码实现

class CPU
{
public:
  virtual void calculate() = 0;
};
class VideoCard
{
public:
  virtual void display() = 0;
};
class Storage
{
public:
  virtual void storage() = 0;
};
class Computer
{
public:
  Computer(CPU* cpu, VideoCard* vc, Storage* sto)
  {
      m_cpu = cpu;
      m_vc = vc;
      m_sto = sto;
  }
  //提供一个工作的函数
  void work()
  {
      m_cpu->calculate();
      m_vc->display();
      m_sto->storage();
  }
  //提供析构函数释放3个电脑零件
  ~Computer()
  {
      //释放CPU零件
      if (m_cpu != NULL)
      {
          delete m_cpu;
          m_cpu = NULL;
      }
      //释放显卡零件
      if (m_vc != NULL)
      {
          delete m_vc;
          m_vc = NULL;
      }
      //释放内存条零件指针
      if (m_sto != NULL)
      {
          delete m_sto;
          m_sto = NULL;
      }
  }
private:
  CPU* m_cpu;//CPU零件指针
  VideoCard* m_vc;//显卡零件指针
  Storage* m_sto;//内存条零件指针
};
//Intel
class IntelCPU :public CPU
{
public:
  virtual     void calculate()
  {
      cout << "Intel的CPU开始计算了" << endl;
  }
};
class IntelVideoCard :public VideoCard
{
public:
  virtual     void display()
  {
      cout << "Intel的显卡开始显示了" << endl;
  }
};
class IntelMemory :public Storage
{
public:
  virtual     void storage()
  {
      cout << "Intel的内存条开始存储了" << endl;
  }
};
//Lenovo
class LenovoCPU :public CPU
{
public:
  virtual     void calculate()
  {
      cout << "Lenovo的CPU开始计算了" << endl;
  }
};
class LenovoVideoCard :public VideoCard
{
public:
  virtual     void display()
  {
      cout << "Lenovo的显卡开始显示了" << endl;
  }
};
class LenovoMemory :public Storage
{
public:
  virtual     void storage()
  {
      cout << "Lenovo的内存条开始存储了" << endl;
  }
};
//组装电脑
void test01()
{
  //创建第一台电脑
  Computer* c1 = new Computer(new IntelCPU,new IntelVideoCard, new IntelMemory);
  c1->work();
  delete c1;
  cout << "***********************" << endl;
  //组装第二台电脑
  Computer* c2 = new Computer(new LenovoCPU, new LenovoVideoCard, new LenovoMemory);
  c2->work();
  delete c2;
  cout << "***********************" << endl;
  //组装第三台电脑
  Computer* c3 = new Computer(new LenovoCPU, new IntelVideoCard, new LenovoMemory);
  c3->work();
  delete c3;
}
void main()
{
  test01();
  system("pause");
}

代码解释

首先把CPU,显卡,内存条做成基类并各自添加纯虚函数,强制派生类进行重写。

然后创建Computer类,封装三个零件类的指针,在电脑类的有参构造中传入三个零件的指针并赋值,提供work函数调用各个零件的功能函数。在程序结束之前编译器会自动调用析构,所以我提供一个电脑类的析构函数,释放掉三个零件的指针。

接下来提供两个品牌,有Intel和Lenovo两个品牌的三种零件。对每个品牌的三个零件类进行继承并重写功能函数,提示具体品牌的零件做了什么具体的功能。

最后创建三个电脑,将零件进行组装,可以全部都是Intel也可以都是Lenovo也可以混合着组装。利用new开辟电脑类,直接使用有参构造,将new出来的零件类传给对应的父类指针,完成多态的使用。电脑类创建完毕后调用work函数使电脑运行,随后就将堆区指针删除,防止内存泄露。

运行效果

C++多态的示例详解

以上就是C++多态的示例详解的详细内容,更多关于C++多态的资料请关注服务器之家其它相关文章!

原文链接:https://blog.csdn.net/m0_58618795/article/details/125493384

延伸 · 阅读

精彩推荐
  • C/C++C++实现转置矩阵的循环

    C++实现转置矩阵的循环

    大家好,本篇文章主要讲的是C++实现转置矩阵的循环,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览...

    Alkaid#352910652022-08-05
  • C/C++树存储结构的几种表示方法

    树存储结构的几种表示方法

    今天小编就为大家分享一篇关于树存储结构的几种表示方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来...

    BLSxiaopanlaile12052021-07-24
  • C/C++C语言动态开辟内存详解

    C语言动态开辟内存详解

    这篇文章主要为大家详细介绍了C语言动态开辟内存,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你...

    XATU弟中之弟9102022-10-08
  • C/C++C++实现简单的图书管理系统

    C++实现简单的图书管理系统

    本文给大家分享的是使用C++实现简单的图书管理系统的代码,本系统采用了面向对象的程序设计方法,文中示例代码介绍的非常详细,具有一定的参考价值...

    C++教程网6772021-03-05
  • C/C++C++变量引用的概念介绍

    C++变量引用的概念介绍

    这篇文章主要介绍了C++变量引用的概念介绍,简单提到了与指针概念的不同,通过代码场景分析给大家介绍的非常详细,需要的朋友可以参考下...

    Data菌11762021-12-10
  • C/C++详解C语言之顺序表

    详解C语言之顺序表

    这篇文章主要为大家介绍了C语言的顺序表,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助...

    ぃ咔哇依°ヽ7782022-02-24
  • C/C++C++ 名称空间详情

    C++ 名称空间详情

    当一个项目变得大型之后,我们会引入很多的库,这么一来两个库很可能会定义List、Tree、Node同名的类,编译器要是不考虑这情况的话,程序员调用时就会...

    用户9824330962144652022-01-11
  • C/C++C++利用递归实现走迷宫

    C++利用递归实现走迷宫

    这篇文章主要为大家详细介绍了C++利用递归实现走迷宫,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    春风来不来6852021-08-26