C++编译时多态和运行时多态

2023-11-10


多态就是指一个基类指针根据所指对象的不同而有不同的功能和行为

编译时多态

编译时多态,又叫静态多态、早绑定。编译时多态基于template(模板)的具现化与函数的重载解析,这种多态在编译期进行,因此称为编译期多态。

注意:重载不关心函数返回类型,只关心函数的参数个数、参数类型或参数顺序。

1.模板具现化
以不同的模板参数具现化导致调用不同的函数,如下:

class Animal
{
public :
    void shout() { cout << "发出动物的叫声" << endl; };
};
class Dog
{
public:
     void shout(){ cout << "汪汪!"<<endl; }
};
class Cat
{
public:
     void shout(){ cout << "喵喵~"<<endl; }
};
class Bird
{
public:
     void shout(){ cout << "叽喳!"<<endl; }
};
template <typename T>
void  animalShout(T & t)
{
    t.shout();
}
int main()
{
    Animal anim;
    Dog dog;
    Cat cat;
    Bird bird;
 
    animalShout(anim);
    animalShout(dog);
    animalShout(cat);
    animalShout(bird);
 
    getchar();
}

在编译之前,函数模板中t.shout()调用的是哪个接口并不确定。在编译期间,编译器推断出模板参数,因此确定调用的shout是哪个具体类型的接口。不同的推断结果调用不同的函数,这就是编译器多态。

2.函数重载
程序在编译之前就知道用哪个函数,即在一个类中有相同的函数名,也就是函数重载,重载函数的参数个数,参数类型或参数顺序三者中必须有一个不同。例子如下:


#include<Windows.h>
#include<iostream>
using namespace std;
 
int Add(int a, int b)
{
 
	return a + b;
 
}
 
double Add(double a, double b)
{
 
	return a + b;
}
 
float Add(float a, float b)
{
 
	return a + b;
 
}
int main()
{
 
	cout<<Add(1,2)<<endl;
	cout<<Add(3.5, 4.5)<<endl;
	cout << Add(2.22, 3.33) << endl;
	
	system("pause");
	return 0;

运行时多态

运行时多态,又叫动态多态、晚绑定、覆盖 、重写。运行时多态基于虚函数机制实现多态的功能在不同但是具有继承关系的类中有相同的函数名,这样的实现方式也叫重写。

运行期多态的设计思想要归结到类继承体系的设计上去。对于有相关功能的对象集合,我们总希望能够抽象出它们共有的功能集合,在基类中将这些功能声明为虚接口(虚函数),然后由子类继承基类去重写这些虚接口,以实现子类特有的具体功能。典型地我们会举下面这个例子:
在这里插入图片描述

class Animal
{
public :
    virtual void shout() = 0;
};
class Dog :public Animal
{
public:
    virtual void shout(){ cout << "汪汪!"<<endl; }
};
class Cat :public Animal
{
public:
    virtual void shout(){ cout << "喵喵~"<<endl; }
};
class Bird : public Animal
{
public:
    virtual void shout(){ cout << "叽喳!"<<endl; }
};

int main()
{
    Animal * anim1 = new Dog;
    Animal * anim2 = new Cat;
    Animal * anim3 = new Bird;
     
   //藉由指针(或引用)调用的接口,在运行期确定指针(或引用)所指对象的真正类型,调用该类型对应的接口
    anim1->shout();
    anim2->shout();
    anim3->shout();
 
    //delete 对象
    ...
   return 0;
}

两种多态的优缺点

运行期多态优点

  1. OO设计中重要的特性,对客观世界直觉认识。

运行期多态缺点

  1. 运行期间进行虚函数绑定,提高了程序运行开销。
  2. 虚表指针增大了对象体积,类也多了一张虚函数表。

编译期多态优点

  1. 在编译器完成多态,提高运行期效率。

编译期多态缺点

  1. 无法实现模板的分离编译,当工程很大时,编译时间不可小觑。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C++编译时多态和运行时多态 的相关文章

随机推荐

  • 卡尔曼滤波(Kalman filter)及预测

    参考文章 https blog csdn net baidu 38172402 article details 82289998 https www jianshu com p 2768642e3abf kalman滤波的作用 1 数据 滤
  • 多层感知机的简洁实现

    import torch from torch import nn from torch nn import init import numpy as np import sys import torchvision from torchv
  • python 中,空的list是否等于None

    文章目录 最近在写测试用例过程中 在判断一个list为空时 随手写下了如下代码 if listinstance is None do something pass 发现当list为空时 程序死活进不去后面的处理语句 于是发现了以下相关文章
  • 从Java到Go:掌握Go语言开发地理位置服务

    目录 目录 1 为什么选择Go 2 Go语言基础 2 1 语法结构 2 2 变量 常量和类型 2 3 函数
  • 位运算技巧集

    位运算技巧集 一般用0xfffffff这种16位数 代替32位二进制数 Java中的幂指数运算不能是 这个符号代表的是异或运算符 与或非异或 两个大于号 向右移位运算 一般可以通过先将需要处理的数字变为二进制数 在观察数字 运算和最终结果之
  • python tcp连接状态判断_Socket套接字连接状态判断,接收数据笔记

    最近工作中涉汲到一些Socket 方面应用 如断线重连 连接状态判断等 今天做了一些总结 1 判断Socket 连接状态 通过 Poll 与 Connected 结合使用 重点关注 SelectRead 模式 方法名 Socket Poll
  • 刷脸支付市场谁才会是最后的大赢家

    2019年 刷脸支付设备的更新非常频繁 支付宝跟微信都推出了自己更新的刷脸设备 这是中国银联也开始战略规划准备迈进人脸识别这个移动支付市场 那么最后谁才会是最后的大赢家呢 每个行业 似乎都有相生相克的行业对手 他们之间的每一次交手 都能成为
  • 睿智的目标检测56——Pytorch搭建YoloV5目标检测平台

    睿智的目标检测56 Pytorch搭建YoloV5目标检测平台 学习前言 源码下载 YoloV5改进的部分 不完全 YoloV5实现思路 一 整体结构解析 二 网络结构解析 1 主干网络Backbone介绍 2 构建FPN特征金字塔进行加强
  • AD629测量负载电流的电路原理详解——精妙绝伦的电路设计

    AD629是ADI公司的一款精密差动放大器 可以承受最大270V的共模电压 使用AD629测量负载电流可以实现在有效抑制共模电压的同时放大差模电压以测量负载电流 如果要测量一个很小的差模信号 很多工程师的第一反应肯定是想到使用仪表放大器 然
  • stat 命令 – 显示文件的状态信息

    stat 命令的功能是用于显示文件的状态信息 Linux 系统中每个文件都有三个 历史时间 最后访问时间 ATIME 最后修改时间 MTIME 最后更改时间 CTIME 用户可以使用 stat 命令查看到它们 进而判别有没有其他人修改过文件
  • unity AR开发中遇到的一些错误总结

    1 Vuforia initialization failed 错误提示如下 Vuforia initialization failed UnityEngine Debug LogError Object Vuforia VuforiaAb
  • JDBC 注册数据库驱动语句

    先附上Microsoft SQL Server JDBC Driver 官方下载地址 https www microsoft com zh cn download driver aspx 初学JDBC 由于数据库软件的不同 我不能按着书上的
  • docker安装及修改默认镜像下载路径和配置加速器

    官方安装 Install Docker Engine on Ubuntu Docker Documentation 镜像存储迁移 Ubuntu20 04修改docker镜像存储位置并进行数据迁移 EastWood001 博客园 cnblog
  • C++运算符的重载

    前言 运算符重载是编译器提供给用户自定义的一种更方便的工作方式 定义 其实就是重新定义一些运算符的意思的 比如是让加法可以在类之间进行 当然我们要使用到关键字operator 话不多说 直接上代码 class Stu public frie
  • 华为HCIA-Datacom学习笔记——OSI数据链路层

    系列文章目录 第一章 网络的定义和网络的历史 第二章 数据交换传输形式 第三章 OSI物理层 第四章 OSI数据链路层 文章目录 系列文章目录 第一章 网络的定义和网络的历史 第二章 数据交换传输形式 第三章 OSI物理层 第四章 OSI数
  • Idea常用插件

    Jrebel 热部署插件 修改代码编译就生效 节省大量重启服务时间 热部署支持修改方法代码 方法定义 类定义 接口定义 包括swagger文档 修改资源文件 修改mapper xml 需配合JRebel MybatisPlus插件一起使用
  • QT中设置字体和更改字体颜色

    QT中设置字体和更改字体颜色 对一个文本框lineEdit设置字体 首先我建了一个按钮setFontButton用来设置 并定义了它的相应函数setFont 将setFontButton添加到布局中 并通过connect 设置与setFon
  • golang多版本管理工具g使用(windows)

    1 下载地址 https github com voidint g releases 2 设置环境变量 G MIRROR 值为 https golang google cn dl 由于国内无法自由访问Golang官网 导致查询及下载go版本
  • 关于vs引用nuget包出错的解决办法(自己摸索)

    关于vs引用nuget包出错的解决办法 问题来源 解决办法 问题来源 vs2015在引用不同的版本的nuget安装包时会出现如下提示 An error occurred while retrieving package metadata f
  • C++编译时多态和运行时多态

    编译时多态 运行时多态 两种多态的优缺点 多态就是指一个基类指针根据所指对象的不同而有不同的功能和行为 编译时多态 编译时多态 又叫静态多态 早绑定 编译时多态基于template 模板 的具现化与函数的重载解析 这种多态在编译期进行 因此