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++语言的动多态.那么,问题又来了. 动多态的发生时机是什么? 或者说,动多态发生有哪些条件与限制呢? 下面让我们一起来探究动 ...
随机推荐
- java之面向对象20160818
本文主要是介绍一下java面向对象编程方面的知识,涉及的内容可能有点多,所以可能会感觉比较笼统,详细请参见<Java编程思想>里面比较具体点. 1.面向对象 和遵循设计原则和设计模式, 目 ...
- 用Visual C#开发基于OpenCV的Windows应用程序
http://blog.163.com/wangxh_jy/blog/static/28233883201001581640283/ 关于详细的配置及程序运行截图,请下载:http://downloa ...
- 省选模拟赛 LYK loves graph(graph)
题目描述 LYK喜欢花花绿绿的图片,有一天它得到了一张彩色图片,这张图片可以看做是一张n*m的网格图,每个格子都有一种颜色去染着,我们用-1至n*m-1来表示一个格子的颜色.特别地,-1代表这个颜色是 ...
- bzoj1467 Pku3243 clever Y
1467: Pku3243 clever Y Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 313 Solved: 181[Submit][Status ...
- python之numpy矩阵库的使用(续)
本文是对我原先写的python常用序列list.tuples及矩阵库numpy的使用中的numpy矩阵库的使用的补充.结合我个人现在对线性代数的复习进度来不断更博. Section 1:行列式的计算 ...
- python的StringIO模块
StringIO经常被用来作字符串的缓存,因为StringIO的一些接口和文件操作是一致的,也就是说同样的代码,可以同时当成文件操作或者StringIO操作. 一.StringIO中的常用方法 1.r ...
- 图论:DFS序
DFS序可以把树转到区间上再用高级数据结构维护,比树链剖分好理解很多 一个闭区间就是一棵子树 POJ3321 #include<cstdio> ; ; int n,m,id,cnt; in ...
- NYOJ 1012 RMQ with Shifts (线段树)
题目链接 In the traditional RMQ (Range Minimum Query) problem, we have a static array A. Then for each q ...
- bzoj 2653 二分答案+可持久化线段树
首先离散化,然后我们知道如果对于一个询问的区间[l1,r1],[l2,r2],我们二分到一个答案x,将[l1,r2]区间中的元素大于等于x的设为1,其余的设为-1,那么如果[l1,r1]的最大右区间和 ...
- zedboard学习记录.3.oled,创建IP
环境:win7 .vivado 2017.4 .zedboard rev.d 首先建立工程. 1.Tools -> Create and Package New IP 2.Create AXI4 ...