C++ 静多态与动多态
多态是指通过单一的标识支持不同的特定行为的能力。
C++中有两种多态,称为动多态(运行期多态)和静多态(编译期多态),而静多态主要通过模板来实现,宏也是实现静多态的一种途径。
动多态在C++中是通过虚函数实现的,即在基类中存在一些接口(一般为纯虚函数),子类必须重载这些接口。这样通过使用基类的指针或者引用指向子类的对象,就可以实现调用子类对应的函数的功能。动多态的函数调用机制是执行期才能进行确定,所以它是动态的。
#include <iostream>
using namespace std; class shape
{
public:
virtual void draw() = ;
}; class line : public shape
{
public:
void draw()
{
cout << "line is drawing!" << endl;
}
}; class circle : public shape
{
public:
void draw()
{
cout << "circle is drawing!" << endl;
}
}; int main()
{
shape* pLine = new line;
shape* pCircle = new circle; // line line;
// circle circl;
//
// shape& referenceLine = line; //引用
// shape& referenceCircl = circl;
//
// referenceLine.draw();
// referenceCircl.draw(); pLine->draw();
pCircle->draw();
if( pCircle ) delete pCircle ;
if( pLine ) delete pLine ;
return ;
}
静多态是采用模板机制实现的,没用基类,因此也不用进行绑定。它不采用虚函数机制,所以所有调用在编译期就可确定,因此它是静态的。
#include <iostream>
using namespace std; class line
{
public:
void draw()
{
cout << "line is drawing!" << endl;
}
}; class circle
{
public:
void draw()
{
cout << "circle is drawing!" << endl;
}
}; template<typename T>
void drawShape(T & shape)
{
shape.draw();
} int main()
{
line lining;
circle circling;
drawShape( lining );
drawShape( circling ); return ;
}
动多态的实现要通过虚函数,会产生虚表和虚指针,占用较多的空间,动多态需要在运行期进行绑定,所花费的时间较静多态多。
优点:能处理异类集合(容器中存储基类指针即可)、可执行代码比较小(只需一个多态函数)、可以完全编译而不需要发布源码。
缺点:不能提前检查类型的安全性(如向容器中插入错误类型的对象)、性能低(有层层继承)、耦合性高(继承的耦合性高于组合)。
静多态在空间和时间上都比动多态表现的好,因此在其他的条件相同的情况下,应该更多的使用静多态。但是静多态也有一些缺点,如它不能够处理异类的集合,也没有动多态灵活。并且现在大部分编译器不支持模板的分离编译,因此要将声明和实现写在一个文件中,这样会暴露更多的细节。
优点:具体类可以只实现需要的接口、生成代码性能高(无需通过指针的间接调用,非虚函数具有更多的内联机会)、有更好的类型安全性(类型在编译期就进行检查)、耦合性低(各个类相互独立)、集合的元素类型不再局限于指针。
缺点:不能处理异类集合、可执行代码比较大(代码膨胀)、模板库源码需要发布、对模板实参类型有约束(比如需要该类型实现了operator<)。
到底用动多态还是静多态,应该根据情况综合考虑决定。我们也可以结合动多态和静多态来获得一个很好的效率和灵活性。
C++ 静多态与动多态的更多相关文章
- C++多态(静多态和动多态)
如今的C++已经是个多重泛型编程语言(multiparadigm programming lauguage),一个同时支持过程形式(procedural).面向对象形式(object-oriented ...
- C++ | 动多态 | 虚函数表
多态机制 C++语言有三大特性:封装.继承.多态. 其中所谓的多态,即 "同一接口,不同形态".接口在我们 C/C++ 语言中可以理解为函数名,不同形态可以理解为函数执行的功能不同 ...
- C++基础知识-Day8
2.类的作用域运算符 shadow 在我们之前讲的内容中,我们会发现一种情况,就是在我们在不同类中的打印函数我们都是尽量让其名字不同,那么为什么会有这种情况呢?首先我们来看一个函数 void func ...
- (C/C++学习笔记) 十七. 面向对象程序设计
十七. 面向对象程序设计 ● 面向对象程序设计的基本概念 ※ 类实际上是一种复杂的数据类型,它不仅包含不同类型的数据,还包含对这些数据的一些必要的操作. 而对象则是这种复杂的数据类型的一个变量. 类是 ...
- (C/C++学习)5.C++中的虚继承-虚函数-多态解析
说明:在C++学习的过程中,虚继承-虚函数经常是初学者容易产生误解的两个概念,它们与C++中多态形成的关系,也是很多初学者经常产生困惑的地方,这篇文章将依次分别对三者进行解析,并讲述其之间的联系与不同 ...
- 深入C++06:深入掌握OOP最强大的机制
深入掌握OOP最强大的机制 1. 继承的基本意义 类与类之间的关系:①组合:a part of ... 一部分的关系:②继承: a kind of ... 属于同一种的关系: 继承的本质:a. 代码的 ...
- C++ template —— 动多态与静多态(六)
前面的几篇博文介绍了模板的基础知识,并且也深入的讲解了模板的特性.接下来的博文中,将会针对模板与设计进行相关的介绍.------------------------------------------ ...
- C++动多态和静多态
动多态的设计思想:对于相关的对象类型,确定它们之间的一个共同功能集,然后在基类中,把这些共同的功能声明为多个公共的虚函数接口.各个子类重写这些虚函数,以完成具体的功能.客户端的代码(操作函数)通过指向 ...
- C++ | 动多态的发生时机
探究动多态的发生时机 有了虚函数和虚函数表为动多态提供支持,从而可以实现C++语言的动多态.那么,问题又来了. 动多态的发生时机是什么? 或者说,动多态发生有哪些条件与限制呢? 下面让我们一起来探究动 ...
随机推荐
- android ndk 编译的时候指令集的选取
android ndk在编译的时候默认生成的是thumb指令(拇指)不是arm(手臂)指令,但是有时候在看反汇编的时候,不太熟悉thumb指令或者说thumb指令看起来更费劲,需要生成arm指令,这个 ...
- mysql三-6:完整性约束
一 介绍 约束条件与数据类型的宽度一样,都是可选参数 作用:用于保证数据的完整性和一致性 主要分为: PRIMARY KEY (PK) 标识该字段为该表的主键,可以唯一的标识记录 FOREIGN KE ...
- [ldap]ldap server安装以及图形化操作
https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-a-basic-ldap-server-on ...
- Ibatis的resultMap和查询数据的对应关系
iBatis和MyBatis 中返回数据对应关系 直接进入主题,现在的项目改用MyBatis了,感觉跟iBatis还是不一样的,比如在判断空值上面,iBatis是有标签的<isNotEmpty& ...
- HDU 1452 欧拉定理
让你求$2004^x$所有因子之和,因子之和函数是积性函数$\sigma(n)=\sum_{d|n}d=\prod_{i=0}^{m}(\sum_{j=0}^{k_i}{P_i^{j}})$可用二项式 ...
- 【洛谷 P4166】 [SCOI2007]最大土地面积(凸包,旋转卡壳)
题目链接 又调了我两个多小时巨亏 直接\(O(n^4)\)枚举4个点显然不行. 数据范围提示我们需要一个\(O(n^2)\)的算法. 于是\(O(n^2)\)枚举对角线,然后在这两个点两边各找一个点使 ...
- SMB MS17-010 利用(CVE-2017-0144 )
exploit-db : https://www.exploit-db.com/exploits/42315/ 该漏洞的影响版本很广泛:Microsoft Windows Windows 7/8.1/ ...
- Spring Data JPA笔记
1. Spring Data JPA是什么 Spring Data JPA是Spring Data大家族中的一员,它对对持久层做了简化,用户只需要声明方法的接口,不需要实现该接口,Spring Dat ...
- docker-It's possible that too few managers are online. Make sure more than half of the managers are online.
问题:docker ---- It's possible that too few managers are online. Make sure more than half of the manag ...
- 安装node-sass的正确姿势【转】
安装 node-sass 的时候总是会各种不成功,今天我琢磨了一会儿总算知道要怎么解决了. 首先要知道的是,安装 node-sass 时在 node scripts/install 阶段会从 gith ...