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),多态性是将接口与实现进行分离:用形象的语言来解释就是实现以共同 ...
随机推荐
- 7.2 Mybatis
7.2 Mybatis 平时我们都用JDBC访问数据库,除了需要自己写SQL之外,还必须操作Connection, Statement, ResultSet 这些其实只是手段的辅助类. 不仅如此,访问 ...
- Nginx事件管理之ngx_event_core_module模块
1. 概述 ngx_event_core_module 模块是一个事件类型的模块,它在所有事件模块中的顺序是第一位.它主要完成以下两点任务: 创建连接池(包括读/写事件): 决定究竟使用哪些事件驱动机 ...
- linux开启数据库远程连接
1.阿里云开启数据库端口 3306 2. 修改 Mysql-Server 用户配置 mysql -uroot -p(注意此用户必须要有最高级权限才行 默认root用户) mysql> USE m ...
- Oracle 变量 之 define variable declare 用法及区别
Oracle 变量 之 define variable declare 用法及区别 Table of Contents 1. 扯蛋 2. define和accept 3. variable 3.1. ...
- CSS操作表格的边框和表格的属性示例代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- jenkins介绍及其简单操作
一.jenkins简介 Jenkins是一个开源软件项目,是基于Java开发的一种持续集成工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能. Jenkins功能包 ...
- Nginx 日志打印POST数据
在工作中,开发希望能从Nginx日志中获取POST的数据信息,先记录下来 在日志格式后面加上 $request_body 配置信息 log_format main '$remote_addr - $r ...
- visual studio 2019 中初始化 vue.js 项目
vs项目模板,webpack模板的创建方式在vs里创建后,npm install的过程会卡很久,暂时原因不明,感觉应该是文件太多,需要写入太多零碎文件. 试了几种初始化方法,还是用最新cli创建最好, ...
- golang(06)函数介绍
原文链接 http://www.limerence2017.com/2019/09/11/golang11/#more 函数简介 函数是编程语言中不可缺少的部分,在golang这门语言中函数是一等公民 ...
- 利用netsh命令设置IP地址/DNS服务器地址
一.设置IP地址 1. 自动获取IP地址: netsh interface ip set address [name=]"本地连接" [source=]dhcp 2. 手动设置IP ...