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删除指针。注意删除指针只是删除了那一块地址,该指针的类型是不变的,还可以多次利用,指向不同的子类对象。

运行效果

案例二:制作饮品

案例要求

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

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

代码实现

#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删除堆区父类指针,以免内存泄漏。

运行效果

案例三:电脑组装

案例要求

电脑主要组成部件为 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++多态的资料请关注我们其它相关文章!

(0)

相关推荐

  • C++之多态(内容不错)

    编译环境:WIN10 VS2017 这篇博客有点长,但都是满满的干货,一定要看到最后,那才是重点. 什么是多态? 顾名思义就是同一个事物在不同场景下的多种形态. 下面会具体的详细的介绍. 静态多态 我们以前说过的函数重载就是一个简单的静态多态 int Add(int left, int right) { return left + right; } double Add(double left, int right) { return left + right; } int main() { A

  • C++学习之多态的使用详解

    目录 前言 多态 向上转型 向下转型 作用域 前言 最近为了完成数据库系统的实验,又复习起了<C++ Primer>,上一次看这本巨著也是大二下的六月份,那时看面向对象程序编程这一章还云里雾里的,没有领会多态的奥妙,学完 Java 之后回头再看这一章发现对多态有了更好的理解.好记性不如烂笔头,本篇博客将会对 C++ 的多态机制做一个不太详细的总结,希望下一次不需要从头再看一遍<C++ Primer>了 _(:з」∠)_. 多态 多态离不开继承,首先来定义一个基类 Animal,里面

  • C++多态实现方式详情

    注:文章转自公众号:Coder梁(ID:Coder_LT) 在我们之前介绍的继承的情况当中,派生类调用基类的方法都是不做任何改动的调用. 但有的时候会有一些特殊的情况,我们会希望同一个方法在不同的派生类当中的行为是不同的.举个简单的例子,比如speak方法,在不同的类当中的实现肯定是不同的.如果是Human类,就是正常的说话,如果是Dog类可能是汪汪,而Cat类则是喵喵. 在这种情况下只是简单地使用继承是无法满足我们的要求的,最好能够有一个机制可以让方法有多种形态,不同的对象去调用的逻辑不同.这

  • 详解C++ 多态的实现及原理

    C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数.如果对象类型是派生类,就调用派生类的函数:如果对象类型是基类,就调用基类的函数 1:用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数. 2:存在虚函数的类都有一个一维的虚函数表叫做虚表,类的对象有一个指向虚表开始的虚指针.虚表是和类对应的,虚表指针是和对象对应的. 3:多态性是一个接口多种实现,是面向对象的核心,分为类的多态性和函数的多态

  • C++面向对象之多态的实现和应用详解

    前言 本文主要给大家介绍的是关于C++面向对象之多态的实现和应用的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 多态 大家应该都听过C++三大特性之一多态,那么什么多态呢?多态有什么用?通俗一点来讲-> 多态性可以简单地概括为"一个接口,多种方法",程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念.当多态应用形参类型的时候,可以接受更多的类型.当多态用于返回值类型的时候,可以返回更多类型的数据.多态可以让你的代码拥有更好的扩展性. 多态分

  • 一篇文章带你了解C++多态的实现原理

    目录 虚函数和多态 多态的作用 多态的一个例子 构造函数和析构函数中存在多态吗? 多态的实现原理 虚函数表 虚析构函数 纯虚函数和抽象类 总结 虚函数和多态 虚函数: 在类的定义中,前面有 virtual 关键字的成员函数称为虚函数 virtual 关键字只用在类定义里的函数声明中,写函数体时不用 比如: class Base { virtual int Fun() ; // 虚函数 }; int Base::Fun() // virtual 字段不用在函数体时定义 { } 多态的表现形式 派生

  • C++多态的示例详解

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

  • java面向对象设计原则之里氏替换原则示例详解

    目录 概念 实现 拓展 概念 里氏替换原则是任何基类出现的地方,子类一定可以替换它:是建立在基于抽象.多态.继承的基础复用的基石,该原则能够保证系统具有良好的拓展性,同时实现基于多态的抽象机制,能够减少代码冗余. 实现 里氏替换原则要求我们在编码时使用基类或接口去定义对象变量,使用时可以由具体实现对象进行赋值,实现变化的多样性,完成代码对修改的封闭,扩展的开放.如:商城商品结算中,定义结算接口Istrategy,该接口有三个具体实现类,分别为PromotionalStrategy (满减活动,两

  • Go语言基础结构体用法及示例详解

    目录 概述 语法 结构体定义的三种形式 第一种[基本的实例化] 第二种[指针类型的结构体] 第三种[取结构体的地址实例化,通过&的操作] 初始化结构体 键值对初始化结构体 值列表填充结构体 匿名结构体 访问结构体成员 结构体作为函数参数 结构体指针 添加结构体方法 总结 示例 概述 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合 语法 定义结构体[标识自定义结构体的名称,在同一个包内不能重复] type 结构名 struct { 字段1: 字段1的值, 字段2: 字段2的值, ...

  • Go语言基础模板设计模式示例详解

    目录 概述 模板模式生活案例 策略模式涉及到两个角色 UML 总结 示例 概述 模板方法模式定义了一个算法的步骤,并允许子类别为一个或多个步骤提供其实践方式.让子类别在不改变算法架构的情况下,重新定义算法中的某些步骤 确定了步骤的执行顺序,单某些步骤因环境或人等因素具体实现是未知的 模板模式生活案例 请客吃饭[点菜->吃东西->结账],每个人点菜不一样,吃东西不一样,结账也不一样从某地到某地[起点->出行方式->终点]起点和终点不一一样,但是每个人出行方式是不一样的 Go没有封装.

  • AngularJS的Filter的示例详解

    贴上几个有关Filter使用的几个示例. 1. 首先创建一个表格 <body ng-app="app"> <div class="divAll" ng-controller="tableFilter"> <input type="text" placeholder="输入你要搜索的内容" ng-model="key"> <br><br

  • bat批处理 if 命令示例详解

    if 命令示例详解 if,正如它E文中的意思,就是"如果"的意思,用来进行条件判断.翻译过来的意思就是:如果符合某一条件,便执行后面的命令. 主要用来判断,1.两个"字符串"是否相等:2.两个数值是大于.小于.等于,然后执行相应的命令. 当然还有特殊用法,如结合errorlevel:if errorlevel 1 echo error 或者结合defined(定义的意思):if defined test (echo It is defined) else echo 

  • Docker-Compose的使用示例详解

    Docker Compose是一个用来定义和运行复杂应用的Docker工具.使用Compose,你可以在一个文件中定义一个多容器应用,然后使用一条命令来启动你的应用,完成一切准备工作. - github.com/docker/compose docker-compose是用来在Docker中定义和运行复杂应用的工具,比如在一个yum文件里定义多个容器,只用一行命令就可以让一切就绪并运行. 使用docker compose我们可以在Run的层面解决很多实际问题,如:通过创建compose(基于YU

  • jQuery.Validate表单验证插件的使用示例详解

    jQuery Validate 插件为表单提供了强大的验证功能,让客户端表单验证变得更简单,同时提供了大量的定制选项,满足应用程序各种需求. 请在这里查看示例 validate示例 示例包含 验证错误时,显示红色错误提示 自定义验证规则 引入中文错误提示 重置表单需要执行2句话 源码示例 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <

  • JavaScript中自带的 reduce()方法使用示例详解

    1.方法说明 , Array的reduce()把一个函数作用在这个Array的[x1, x2, x3...]上,这个函数必须接收两个参数,reduce()把结果继续和序列的下一个元素做累积计算,其效果就是: [x1, x2, x3, x4].reduce(f) = f(f(f(x1, x2), x3), x4) 2. 使用示例 'use strict'; function string2int(s){ if(!s){ alert('the params empty'); return; } if

  • php示例详解Constructor Prototype Pattern 原型模式

    原型模式中主要角色 抽象原型(Prototype)角色:声明一个克隆自己的接口 具体原型(Concrete Prototype)角色:实现一个克隆自己的操作 当一个类大部分都是相同的只有部分是不同的时候,如果需要大量这个类的对象,每次都重复实例化那些相同的部分是开销很大的,而如果clone之前建立对象的那些相同的部分,就可以节约开销. 针对php的一种实现方式就是__construct()和initialize函数分开分别处理这个类的初始化,construct里面放prototype也就是公共的

随机推荐