C++ —面向对象之多态的实现与应用
多态
class Person
{
public: virtual void BuyTickets() { cout << " 买票" << endl; } protected: string _name; // 姓名
}; class Student : public Person
{
public: virtual void BuyTickets() { cout << " 买票-半价 " << endl; } protected: int _num; //学号
}; void Fun(Person& p)
{ p.BuyTickets();
} void Test()
{ Person p; Student s; Fun(p); Fun(s);
}
int main()
{ Test(); system("pause"); return 0;
}
![](/assets/blank.gif)
通过汇编来分析多态的实现
class Person
{
public: virtual void BuyTickets() { cout << " 买票" << endl; } protected: string _name; // 姓名
}; class Student : public Person
{
public: virtual void BuyTickets() { cout << " 买票-半价 " << endl; } protected: int _num; //学号
};
void Fun(Person& p)
{ p.BuyTickets();
} void Test()
{ Person p; Student q; Person* ptr = &q; p.BuyTickets(); ptr->BuyTickets();
}
int main()
{ Test(); system("pause"); return 0;
}
![](/assets/blank.gif)
再定义一个类class Fish//鱼 。它的函数也为breathe()
再定义一个类class Sheep //羊。它的函数也为breathe()
为了简化代码,将Fish,Sheep定义成基类Animal的派生类。
然而Fish与Sheep的breathe不一样,一个是在水中通过水来呼吸,一个是直接呼吸空气。所以基类不能确 定该如何定义
一般情况下(没有涉及virtual函数),当我们用一个指针/引用调用一个函数的时候,被调用的函数是取决于这个指针
/引用的类型。即如果这个指针/引用是基类对象的指针/引用就调用基类的方法;如果指针/引用是派生类对象的指针/引
用就调用派生类的方法,当然如果派生类中没有此方法,就会向上到基类里面去寻找相应的方法。这些调用在编译阶段
就确定了。
当设计到多态性的时候,采用了虚函数和动态绑定,此时的调用就不会在编译时候确定而是在运行时确定。不在单独考
虑指针/引用的类型而是看指针/引用的对象的类型来判断函数的调用,根据对象中虚指针指向的虚表中的函数的地址来
确定调用哪个函数。
现在我们来一个小练习:
#include<iostream>
#include<Windows.h>
using namespace std; class A
{
public: void foo() { printf("1\n"); } virtual void fun() { printf("2\n"); }
};
class B : public A
{
public: void foo() { printf("3\n"); } void fun() { printf("4\n"); }
};
int main(void)
{ A a; B b; A *p = &a; p->foo(); p->fun(); p = &b; p->foo(); p->fun(); system("pause"); return 0;
}
这道题的运行结果分别是 1 2 1 4,,现在我们来分析为什么?
首先当一个父类类型指针指向父类时,我们应该知道这里没有多态,该怎么调用就怎么调用,所以调用了父类里面的
foo函数和fun函数。现在我们重点来看后面这个,现在B继承了A,我们先判断这里是否有多态现象(1.父类和子类是
否有重写现象
2.是否有父类类型的指针指向子类),现在很明显子类的fun函数重写了父类的fun函数,所以现在p->fun()调用的就
是子类的fun函数,然后foo函数,根本不构成多态,所以这里指针类型是什么那个对象就按那个对象调用。总结一下
当你碰到关于继承的问题,首先判断它里面是否有多态现象,如果没有那就根据指针/引用类型调用。如果有多态的
话,一定要注意根据指针/引用的指向对象判断。
C++ —面向对象之多态的实现与应用相关推荐
- 12 Java面向对象之多态
JavaSE 基础之十二 12 Java面向对象之多态 ① 多态的概念及分类 多态的概念:对象的多种表现形式和能力 多态的分类 1. 静态多态:在编译期间,程序就能决定调用哪个方法.方法的重载就表现出 ...
- swift面向对象之多态与继承
swift面向对象之多态与继承 1.多态 运行时多态 运行时多态的要点 1.要有继承关系的存在 2.子类要重写父类的方法 3.父类类型的引用指向子类实例 2.继承 1.继承的注意 继承可以用于类而不能 ...
- Golang笔记-面向对象编程-多态/类型断言
面向对象编程-多态 基本介绍 变量(实例)具有多种形态.面向对象的第三大特征,在 Go 语言,多态特征是通过接口实现的.可 以按照统一的接口来调用不同的实现.这时接口变量就呈现不同的形态. 快速入门 ...
- Java 面向对象:多态的理解
Java 面向对象:多态的理解 一.多态的定义 一个对象的实际类型是确定的,但可以指向引用对象的类型可以有很多(父类,有关系的类) 操作符的多态 +可以作为算数运算,也可以作为字符串连接 类的多态 父 ...
- python面向对象三大特性_Python面向对象之多态原理与用法案例分析
本文实例讲述了Python面向对象之多态原理与用法.分享给大家供大家参考,具体如下: 目标 多态 面向对象三大特性 封装 根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中 定义类的准则 继承 ...
- python中的多态用法_Python面向对象之多态原理与用法案例分析
本文实例讲述了Python面向对象之多态原理与用法.分享给大家供大家参考,具体如下: 目标 多态 面向对象三大特性 封装 根据 职责 将 属性 和 方法 封装 到一个抽象的 类 中 定义类的准则 继承 ...
- Python面向对象编程---多态
Python面向对象编程-多态 定义: 是一种使用对象的方式,子类重写父类的方法(非必须),调用不同子类对象的相同父类方法,可以产生不同的执行结果,简言之就是:传入不同的对象,产生不同的结果. 好处: ...
- Java面向对象之多态(来源于身边的案例)
2019年1月3日 星期四 Java面向对象之多态(来源于身边的案例) 1. 为什么要用多态? 1.1 多态是面向对象的三大特性之一 1.2 多态是基于接口设计的模型 1.3 多态具有横向扩展特性 1 ...
- Java面向对象:多态——基于继承的向上转型、方法重写、动态绑定
Java面向对象:多态 1.多态的概念 2.向上转型和向下转型 (1)向上转型 (2)向下转型 3.方法重写 4.动态绑定与静态绑定 5.多态的优缺点 ======================== ...
- Python学习 - 面向对象之多态
Python学习 - 语法入门:https://blog.csdn.net/wanzijy/article/details/125287855 Python学习 - 数据类型:https://blog ...
最新文章
- golang struct 转map 及 map[string]*Struct 初始化和遍历
- Linux du命令和df命令区别
- 江西计算机一级考试教程,江西省2019年下半年计算机一级考试复习教程:计算机基础及MS Office应用上机指导...
- 如何用VS2005制作Web安装程序
- 在WEB开发的时候导入各种jar包
- python可打印字符_测试一个python字符串是否可打印
- Windows+Python3.7下自动生成requirements.txt文件
- 计算机图形学与混合现实研讨会GAMES: Graphics And Mixed Environment Seminar
- 生活中运筹学的3个小案例_10个“乡村庭院”设计案例,生活在乡下,家家都有自己的小庭院...
- java删除指定文件后重新建立文件系统_java file 操作之创建、删除文件及文件夹...
- 数字后端概念——MIM cell
- 常识性知识,高速快捷知识
- jquery获取元素(父级的兄弟元素的子元素)
- 居家办公的团队协作模式改进思考
- python中wheel什么意思_某个wheel(.whl)包的依赖关系是什么?
- 每日小技巧——教你用一行Python代码去除照片背景
- win+shift+s截图保存在哪_Windows 被冷落的 WIN 键,其实比你想的更好用
- 湖南工程学院计算机与通讯学院肖鹏,基于区间分析无迹粒子滤波的移动机器人SLAM方法...
- 安卓系统再曝高危漏洞!大部分手机都可能被黑客控制
- 李彦宏提案的思路:基于实践、崇尚技术、关注民生