多态
多态的基本概念
多态是C++面向对象三大特性之一
多态分为两类
静态多态:函数重载 和 运算符重载 属于 静态多态,复用函数名
动态多态:派生类 和 虚函数 实现运行时多态
静态多态和动态多态区别:
(1)静态多态的函数地址早绑定  –  编译阶段确定函数地址
(2)动态多态的函数地址晚绑定  –  运行阶段确定函数地址
下面通过案例进行讲解多态
#include<iostream>
using namespace std;//多态
class Animal{
public:virtual void speak(){    //加上virtual后,函数变为虚函数cout << "动物在说话" << endl;}
};
class Cat :: public Animal{
public:void speak(){cout << "小猫在说话" << endl;}
}
18行:void doSpeak(Animal &animal){    //Animal &animal = cat  父类的引用在指向子类的对象//静态多态animal.speak();    //这里调用的是父类的speak()函数,也就是动物在说话,因为这里函数的地址是早绑定的,也就是一开始就绑定了父类中的speak()函数,在编译阶段就确定了函数地址//如果想执行让猫说话,那么这个函数地址就不能提前绑定,需要在运行阶段进行绑定,地址晚绑定,解决方法,在speak()函数前加virtual,将函数更改为虚函数//动态多态animal.speak();  //这里就是猫在说话}
void test01(){Cat cat;doSpeak(cat);
}
int main(){test01();system("pause") ;return 0;
}
总结:
动态多态满足条件
1、有继承关系
2、子类要重写父类的虚函数(子类中重写函数时可以不用加virtual,但是父类中必须加)
动态多态使用
父类的指针或者引用,执行子类对象(也就是第18行的代码)
多态的底层原理:
#include<iostream>
using namespace std;//多态
class Animal{
public:void speak(){    //加上virtual后,函数变为虚函数cout << "动物在说话" << endl;}
};
class Cat :: public Animal{
public:void speak(){cout << "小猫在说话" << endl;}
}
void doSpeak(Animal &animal){    //Animal &animal = cat  父类的引用在指向子类的对象animal.speak();   animal.speak();
}
void test01(){Cat cat;doSpeak(cat);
}
void test02(){cout << "sizeof Animal = " << sizeof(Animal) << endl; //现在Animal类中只有一个非静态的成员函数,他不属于类的对象,是分开存储的,那Animal相当于是一个空类,那么他的大小就是sizeof(Animal) = 1;//如果加上virtual关键字,那么sizeof(Animal) = 4,这4个字节是一个指针,如图1详解
}
int main(){test01();test02();system("pause") ;return 0;
}
图1
子类将父类拷贝一份之后speak函数的入口地址是Animal类中的speak函数地址,&Cat :: speak 这个代码将speak函数的入口地址变为Cat对象的speak函数地址,然后会将原来子类中&Animal::speak函数的地址覆盖掉,如下图所示
这里就相当于子类将父类的虚函数给替换掉了,但是父类中的虚函数并没有发生改变
当父类的指针或者引用指向子类对象的时候,发生多态
Animal *animal = cat ;
animal.speak();
由于指向的是一个cat对象,那么他会去cat的虚函数表中去找speak函数,这是在运行阶段
 
多态案例一-计算器类
案例描述:
分别利用普通写法和多态技术,设计实现两个操作数进行运算的计算器类
多态的优点:
(1)代码组织结构清晰
(2)可读性强
(3)利于前期和后期的扩展以及维护
include<iostream>
using namespace std;//分别利用普通写法和多态技术实现计算器
//普通写法
class Calculator{
public:int getResu1t(string oper){if (oper == "+"){return m_Num1 + m_Num2 ;}else if (oper == "-"){return m_Num1 - m_Num2;}else if (oper == "*"){return m_Num1 * m_Num2;}//如果想扩展新的功能,需要修改源码int m_Num1 ;//操作数1int m_Num2;//操作数2
};void test01(){
//创建计算器对象Caiculator c;c.m_Num1 = 10;c.m_Num2 = 10;cout << c.m_Num1 << " + " << c.m_Num2〈<<" = " << c.getResult("+") << end1;//20cout << c.m_Num1 << " - " << c.m_Num2〈<<" = " << c.getResult("-") << end1;//0cout << c.m_Num1 << " * " << c.m_Num2〈<<" = " << c.getResult("*") << end1;//100
}//利用多态实现计算器
//实现计算器抽象类
class AbstractCalculator
public:virtual int getResult(){return 0;}int m_Num1;int m_Num2;
};
//加法计算器类
class AddCalculator : public AbstractCalculator{
public:virtual int getResult(){return m_Num1 + m_Num2;}
}
//减法计算器类
class SubCalculator : public AbstractCalculator{
public:virtual int getResult(){return m_Num1 - m_Num2;}
}
void test02(){//多态使用条件//父类指针或者引用指向子类对象AbstractCalculator * abc = new AddCalculator;abc->m_Num1 = 10;abc->m_Num2 = 10;cout << abc->m_Num1 <<"+"<< abc->m_Num2<< " = " << abc->getResult() << endl;//用完记得销毁delete abc;abc = new SubCalculator;abc->m_Num1 = 10;abc->m_Num2 = 10;cout << abc->m_Num1 <<"-"<< abc->m_Num2<< " = " << abc->getResult() << endl;delete abc;
}
int main(){test01();test02();system("pause");return 0;
}
多态带来的好处:
1、组织结构清晰
2、可读性强
3、对于前期和后期扩展以及维护性高
案例三:

案例描述:

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

将每个零件封装出抽象基类,并且提供不同的厂商生产不同的零件,例如Intel厂商和Lenovo厂商创建电脑类提供让电脑工作的函数,并且调用每个零件工作的接口

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

#include <iostream>
#include <string>
using namespace std;class CPU{
public:virtual void run_CPU() = 0;
};
class Screem{
public:virtual void run_screem() = 0;
};
class RAM{
public:virtual void run_ram() = 0;
};
class Computer{
public:Computer(CPU *cpu,Screem *screem,RAM *ram){m_CPU = cpu;m_screem = screem;m_RAM = ram;}~Computer(){if(m_CPU == NULL){delete m_CPU;m_CPU = NULL;}if(m_screem == NULL){delete m_screem;m_screem = NULL;}if(m_RAM == NULL){delete m_RAM;m_RAM = NULL;}}void dowork(){m_CPU->run_CPU();m_screem->run_screem();m_RAM->run_ram();}
private:CPU *m_CPU;Screem *m_screem;RAM *m_RAM;
};
ostream &operator <<(ostream &cout,string &string){cout << string.c_str()<<endl;return cout;
}
class Inter_CPU:public CPU{
public:virtual void run_CPU(){cout << " Inter_CPU is running!"<<endl;}
};
class Inter_Screem:public Screem{
public:virtual void run_screem(){cout <<" Inter_SCREEM is running!"<<endl;}
};
class Inter_RAM:public RAM{
public:virtual void run_ram(){cout << " Inter_RAM is running!"<<endl;}
};
void test01(){Inter_CPU inter_cpu;Inter_Screem inter_screem;Inter_RAM inter_ram;CPU *F_CPU = &inter_cpu;Screem *F_SCREEM = &inter_screem;RAM *F_RAM = &inter_ram;Computer(F_CPU,F_SCREEM,F_RAM).dowork();
}
int main(){test01();system("pause");return 0;
}

C++特性之多态,三个多态案例相关推荐

  1. 【Java基础】 ⾯向对象编程三⼤特性 --封装、继承、多态

    文章目录 封装 继承 多态 封装 把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏.封装是面向对象的特征之一,是对象和类概念的主要特性. 通俗的说 ...

  2. 5000字详细解说什么是面向对象编程的三⼤特性—封装、继承、多态

    封装 把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏.封装是面向对象的特征之一,是对象和类概念的主要特性. 通俗的说,一个类就是一个封装了数据以 ...

  3. 面向对象编程三⼤特性 --封装、继承、多态

    封装 把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏.封装是面向对象的特征之一,是对象和类概念的主要特性. 通俗的说,一个类就是一个封装了数据以 ...

  4. Java OOP 第三章 多态

    Java OOP 多态 文章目录 Java OOP 多态 一.学习目标 二.多态 1.为什么使用多态 2.什么是多态? 3.如何实现多态? 三.向上转型 四.父类作为形参 扩展种植梨树 五.多态的使用 ...

  5. Js三大特性--封装、继承以及多态

    Javascript基于对象的三大特征和C++,Java面向对象的三大特征一样,都是封装(encapsulation).继承(inheritance )和多态(polymorphism ).只不过实现 ...

  6. 初步理解Java的三大特性——封装、继承和多态

    声明:整理自网络,如有雷同,请联系博主处理 一.封装 封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被 ...

  7. Python OOP:面向对象三大特性(封装、继承、多态)、类属性和实例属性、类方法@classmethod、静态方法@staticmethod、函数和类callable、__call__

    一.面向对象三大特性 二.多态 定义:多态是⼀种使⽤对象的⽅式,⼦类重写⽗类⽅法,调⽤不同⼦类对象的相同⽗类⽅法,可以产⽣不同的执⾏结果. 一个父类,可以继承给多个子类,每个不同的子类可以创建多个对象 ...

  8. Java面向对象三大特性(封装、继承、多态)

    文章目录 前言 一.封装 1. 封装的概念 2. private实现封装 3. getter和setter方法 4.封装的好处 二.继承 1. 继承的概念 2. extends实现继承 3. supe ...

  9. Java面向对象之多态(来源于身边的案例)

    2019年1月3日 星期四 Java面向对象之多态(来源于身边的案例) 1. 为什么要用多态? 1.1 多态是面向对象的三大特性之一 1.2 多态是基于接口设计的模型 1.3 多态具有横向扩展特性 1 ...

最新文章

  1. Python中的特殊成员和魔法方法
  2. Cocos2d-js学习--helloword
  3. jhsdb:JDK 9的新工具
  4. js数组截取前5个_我不能没有的5个Vue.js库
  5. Python机器学习:线型回归法04向量化运算
  6. 编写运行java的步骤,【简答题】编写运行Java程序需要经过哪些主要步骤? (30.0分)...
  7. 面试热问——你在前一份工作(实习)学到什么?
  8. 文件管理类函数(1)
  9. matlab中单相整流器,应用Matlab仿单相PWM整流器的一种简单方法
  10. lc滤波器是利用电感的感抗_由浅入深讲解滤波电路工作原理
  11. python中怎么用format居中_python中format函数
  12. AWS 云计算 SQS SNS
  13. 2104.10729阅读笔记
  14. HP 惠普笔记本电脑 禁用触摸板 在插入鼠标后
  15. 超强PCB布线设计经验谈附原理图
  16. QT界面,鼠标滚轮实现缩放问题
  17. 最全工业以太网通讯协议
  18. 车联网赋能末端物流自动驾驶探索
  19. 什么是币圈跨链侧链?
  20. 模块pygame介绍以及库的下载

热门文章

  1. Sqlmap工具使用笔记
  2. Java笔试面试题一(选择)
  3. JAVA之ElasticSearch
  4. 授之以鱼,不如授之以渔
  5. AxMath的常用操作
  6. \newcommand使用技巧兼谈fontsize
  7. codecombat极客战记森林(JavaScript)41-60关卡
  8. Java+SSM旅游管理系统旅行管理(含源码+论文+答辩PPT等)
  9. Web代码安全漏洞深度剖析
  10. 计算机网络和855,骁龙855大概相当于什么年代的电脑CPU?