C++ 多态、虚函数(virtual 关键字)、静态联编、动态联编
函数重写:(在子类中重写父类中的函数)
父类中被重写的函数 依然会继承 给子类。
子类中重写的函数将覆盖父类中的函数。
通过作用域分辨符 :: 可以访问到父类中的函数。
例如:
#include <iostream>
#include <string> using namespace std; class parent
{
public:
void parent_func(int i , int j)
{
cout << "parent_func(int i , int j)"<<i<<','<<j<<endl;
}
}; class subClass : public parent
{
public:
void parent_func(int i , int j)//重写父类中的 void parent_func(int i , int j)
{
cout << "parent_func(int i , int j)"<<i*<<','<<j*<<endl;
}
}; void doPrint(parent *p)//如果是 subClass 声明的对象,将把 subClass类退化为 parent类来处理(C++ 默认)
{
p->parent_func(, );
}
int main()
{
parent p;
subClass s; s.parent::parent_func(,);//使用作用域分辨符 通过subClass 声明的对象 去调用parent类中的 parent_func(int i , int j)函数 doPrint(&p);//使用 parent类对象
doPrint(&s);//使用subClass类对象
}
运行结果:
parent_func(int i , int j),
parent_func(int i , int j),
parent_func(int i , int j),
面向对象期望的行为:
根据实际的对象类型判断如何调用重写函数。
父类指针(引用)指向
父类对象则调用父类中定义的函数
子类对象则调用 子类中 重写 的函数
也就是说期望 void doPrint(parent *p) 这个函数调用的时候,如果是父类的对象则直接调用父类中的 void parent_func(int i , int j) 输出结果为:parent_func(int i , int j)1,2
如果是子类对象 则调用void parent_func(int i , int j) 输出结果为:parent_func(int i , int j)2,4
就需要在 父类中将void parent_func(int i , int j) 改为:virtual void parent_func(int i , int j) 表明此函数为 虚函数 子类通过继承的关系 也将把void parent_func(int i , int j) 修改为 虚函数
-通过virtual 支持多态(C++ 中实现多态的唯一方法)
-被virtual 声明的函数被重写后具备多态的特性
-被virtual 关键字声明的函数叫做虚函数。
修改代码如下:
#include <iostream>
#include <string> using namespace std; class parent
{
public:
virtual void parent_func(int i , int j)
{
cout << "parent parent_func(int i , int j)"<<i<<','<<j<<endl;
}
}; class subClass : public parent
{
public:
void parent_func(int i ,int j)//重写父类中的 void parent_func(int i , int j)
{
cout << "subClass parent_func(int i , int j)"<<i*<<','<<j*<<endl;
}
}; void doPrint(parent *p)
{
p->parent_func(, ); //根据对象类型判断如何调用重写函数。
}
int main()
{
parent p;
subClass s; doPrint(&p);//使用 parent类对象
doPrint(&s);//使用subClass类对象
}
运行结果:
parent parent_func(int i , int j),
subClass parent_func(int i , int j),
多态存在的意义:
-多态在程序运行的过程中展现。
-函数重写必须实现多态,否则无意义
-是面向对象 组件化程序设计 的基础特性
静态联编:
在编译的期间就确定了具体的函数调用(重载函数)
动态联编:
在程序运行后才能确定函数的调用(重写函数)
例如:
#include <iostream>
#include <string> using namespace std; class parent
{
public:
virtual void func(int i )
{
cout << "func(int i )"<<i<<endl;
}
virtual void func(int i , int j)
{
cout << "parent func(int i , int j)"<<i<<','<<j<<endl;
}
virtual void func(int i , int j,int k)
{
cout << "parent func(int i , int j,int k)"<<i<<','<<j<<','<<'k'<<endl;
}
}; class subClass : public parent
{
public:
void func(int i , int j) //等价于 virtual void func(int i , int j)
{
cout << "subClass func(int i , int j)"<<i+j<<endl;
}
void func()
{
cout <<" void func()"<<endl;
}
}; void doPrint(parent *p)
{
p->func(, ); //实现多态特性
}
int main()
{
parent p;
subClass s; p.func();//静态联编
p.func(,);//静态联编
p.func(,,);//静态联编 cout <<endl;
s.func(,);//静态联编 编译时就知道了调用函数,最终会调用到,subClass 类中的 void func(int i , int j) 函数 doPrint(&p);//展现动态联编
doPrint(&s);//展现动态联编
}
运行结果:
func(int i )
parent func(int i , int j),
parent func(int i , int j,int k),,k subClass func(int i , int j)
parent func(int i , int j),
subClass func(int i , int j)
C++ 多态、虚函数(virtual 关键字)、静态联编、动态联编的更多相关文章
- C++构造函数和析构函数调用虚函数时都不会使用动态联编
先看一个例子: #include <iostream> using namespace std; class A{ public: A() { show(); } virtual void ...
- 多态&虚函数
(1).对象类型: a.静态类型:对象声明时的类型,编译的时候确定 b.动态类型:对象的类型是运行时才能确定的 class A {}; class B:pub ...
- C++: 多态 虚函数
一.多态: 1.多态是什么:具有不同功能的函数可以用同一个函数名 2.静态多态:程序编译时决定,通过函数重载实现. 3.动态多态:程序运行时决定,通过虚函数实现. 二.虚函数: 1.引入目的:可以通过 ...
- C#中的虚函数virtual
简单介绍虚函数virtual 在某基类中声明 virtual 并在一个或多个派生类中被重新定义的成员函数称为虚函数. 虚函数的作用就是实现多态性(Polymorphism),多态性是将接口与实现进行分 ...
- C#虚函数virtual详解
在面向对象编程中,有两种截然不同的继承方式:实现继承和接口继承.在实现继承时候,在Java中,所有函数默认都是virtual的,而在C#中所有函数并不默认为virtual的,但可以在基类中通过声明关键 ...
- 十万个为什么:现在还没发现“虚函数virtual”和多态性的优点,估计是因为我还没有编程序吧。
十万个为什么:现在还没发现“虚函数virtual”和多态性的优点,估计是因为我还没有编程序吧.
- C++继承-重载-多态-虚函数
C++ 继承 基类 & 派生类 一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数.定义一个派生类,我们使用一个类派生列表来指定基类.类派生列表以一个或多个基类命名,形式如下: ...
- C++基础 (6) 第六天 继承 虚函数 虚继承 多态 虚函数
继承是一种耦合度很强的关系 和父类代码很多都重复的 2 继承的概念 3 继承的概念和推演 语法: class 派生类:访问修饰符 基类 代码: … … 4 继承方式与访问控制权限 相对的说法: 爹派生 ...
- 虚函数virtual
简单地说,那些被virtual关键字修饰的成员函数,就是虚函数.虚函数的作用,用专业术语来解释就是实现多态性(Polymorphism),多态性是将接口与实现进行分离:用形象的语言来解释就是实现以共同 ...
随机推荐
- 移动端的头部标签和 meta
使用 HTML5 doctype,不区分大小写 <!DOCTYPE html> 更加标准的 lang 属性写法 http://zhi.hu/XyIa <html lang=" ...
- 【Azure】用“Azure Storage Exlporer”进行磁盘拷贝
zure Storage Explorer工具的下载 Azure 存储客户端工具 https://docs.azure.cn/zh-cn/storage/storage-explorers Azure ...
- XPATH了解
特殊标签 找SVG这种特殊标签可以使用[name()='svg'],如//[name()='svg']/[name()='line'][2] 文本 找标签内的文本时可以使用: //*[text()=' ...
- JAVA静态数据的初始化;
①:Java首次会自动对变量进行初始化,其顺序优于构造器: ②:如果一个域是静态的的基本类型域,且也没有对它进行初始化,那么它就会获得基本类型的标准初值,如果它是一个对象引用,那么他的默认初始化值为n ...
- 1.1 从零搭建Go语言开发环境
一.下载 下载地址: Go官网下载地址:https://golang.org/dl/ Go官方镜像站(推荐):https://golang.google.cn/dl/ 版本的选择 Windows平台和 ...
- 后端脚手架搭建--SSM(一)开篇
一.絮叨 一直在计划自己搭建一个后台的管理系统脚手架,也已经开始着手做了,但是做的过程中一直出现混乱的状态.在前端技术选型的时候觉得Vue不错,然后去学了一段时间的Vue,准备拿来在项目里面用.然后又 ...
- FTP\SFTP连接命令
五.ftp连接 输入:ftp 10.18.49.19 2121六.输入账号密码 zhangsan/sdjg34t#七.输入:ls 查看文件是否上传 如上传 输入:bye ...
- 发现使用id定位元操作不了
appium:1.8.0 android系统:8.1.0 发现使用id定位元素,定位之后操作不了 解决办法:'automationName': 'UiAutomator2',
- 【AMAD】coconut -- 简单,优雅,pythonic的函数式编程语言
动机 简介 个人评分 动机 作者的话: 我喜欢函数式编程,我认为函数式编程提供了一个更自然的方式来思考问题,并且代码也更加优雅,易读.不过如果你看过前20个最受欢迎的编程语言,你会发现没有一个式函数式 ...
- 【AMAD】tenacity -- Python中一个专门用来retry的库
动机 简介 用法 基本用法 何时停止 尝试间的等待 何时retry 其它 热度分析 源码分析 个人评分 动机 很多时候,我们都喜欢为代码加入retry功能.比如oauth验证,有时候网络不太灵,我们希 ...