第二十二篇:C++中的多态机制
前言
封装性,继承性,多态性是面向对象语言的三大特性。其中封装,继承好理解,而多态的概念让许多初学者感到困惑。本文将讲述C++中多态的概念以及多态的实现机制。
什么是多态?
多态就是多种形态,就是许多情况下可以互换地使用基类型和派生类型的多种形态。
多态的实现
依赖于动态绑定机制。
动态绑定机制相关
动态绑定是函数实际参数和形式参数绑定的一种方式,它是指我们能够在函数接口中使用继承层次中任意类型的对象,无需关心对象的具体类型。
动态执行接口函数的对象参数的哪个函数得在程序实际执行的时候才能确定
C++中默认不使用动态绑定,要触发动态绑定必须满足两个条件:
1. 接口函数的形式参数必须是引用类型或者指针类型。
2. 动态执行函数(对象参数的成员函数而非接口函数)必须是声明为虚成员函数。
代码实例一
下面代码创建基类对象a,然后创建其派生对象b,当将a,b作为参数传入函数printNum()后,函数让它们分别调用自己的函数getNum():
#include <iostream> using namespace std; // 基类
class A {
public:
A() {a=;}
// **需要动态执行的函数必须声明为虚函数,满足了上条件2。
virtual int getNum() {
return a;
}
private:
int a;
}; // 派生类
class B : public A {
public:
B() {b=;}
// 基类中已经声明过为虚函数了不需要再次声明
int getNum() {
return b;
}
private:
int b;
}; // **接口函数形参声明为引用类型,满足了上条件1。
void printNum(A & a) {
// 当实参为基类对象则调用基类对象的getNum,实参为派生类对象则调用派生类对象的getNum。
cout << a.getNum() << endl;
} int main()
{
A a;
B b; printNum(a);
printNum(b); return ;
}
运行结果:

可以观察到顺利实现了动态绑定,a b分别执行自己的getNum() 函数。
代码实例二
下面代码同样创建基类对象a,然后创建其派生对象b,当将a,b作为参数传入函数printNum()后,函数让它们分别调用自己的函数getNum()(但本例接口函数的形式参数改成了值类型 ):
#include <iostream> using namespace std; // 基类
class A {
public:
A() {a=;}
// **需要动态执行的函数必须声明为虚函数,满足了上条件2。
virtual int getNum() {
return a;
}
private:
int a;
}; // 派生类
class B : public A {
public:
B() {b=;}
// 基类中已经声明过为虚函数了不需要再次声明
int getNum() {
return b;
}
private:
int b;
}; // **接口函数形参声明为值类型,不满足上条件1。
void printNum(A a) {
// 未有实现动态绑定,因此不论实参是何种类型,均执行基类的getNum()函数。
cout << a.getNum() << endl;
} int main()
{
A a;
B b; printNum(a);
printNum(b); return ;
}
运行结果:

可以观察到没有实现动态绑定,a b都执行a的getNum() 函数。这意味着,对象本身并不支持多态,它刚进入函数就被彻底地转换成了形参类型。因此,实现多态要靠的是对象的指针或者引用,而不是对象本身。这也是《C++ Primer》一书中不断强调的东西。
说明
1. 派生类和基类的虚函数类型要一致,只有一种例外 --- 返回对基类类型的引用的虚函数。派生类中的虚函数可以返回基类函数所返回类型的派生类的引用。
2. 基类和派生类的虚函数的默认实参要相同,不然会引起混淆。
小结
封装保证了类的重用( 安全方面 ),继承实现了类的重用,多态则实现了接口的重用。这三个机制体现了C++代码的可重用性,反映了C++在处理大型程序的优势。
第二十二篇:C++中的多态机制的更多相关文章
- Python开发【第二十二篇】:Web框架之Django【进阶】
Python开发[第二十二篇]:Web框架之Django[进阶] 猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...
- Android UI开发第二十八篇——Fragment中使用左右滑动菜单
Fragment实现了Android UI的分片管理,尤其在平板开发中,好处多多.这一篇将借助Android UI开发第二十六篇——Fragment间的通信. Android UI开发第二十七篇——实 ...
- Python之路【第二十二篇】:Django之Model操作
Django之Model操作 一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bi ...
- 【Python之路】第二十二篇--Django【基础篇】
1 Django流程介绍 MTV模式 著名的MVC模式:所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层:他们之间以一种插件似的,松耦合的方式连接在一起. 模型负责业 ...
- 第二十二篇:在SOUI中使用代码向窗口中插入子窗口
使用SOUI开发客户端UI程序,通常也推荐使用XML代码来创建窗口,这样创建的窗口使用方便,当窗口大小改变时,内部的子窗口也更容易协同变化. 但是最近不断有网友咨询如何使用代码来创建SOUI子窗口,特 ...
- 【第二十二篇】从客户端中检测到有潜在危险的 Request.Form 值
提交数据的时候 用js的方法 escape(富文本框的值) 例:escape(UM.getEditor('Content').getContent()); 取值的时候 unescape ...
- Python之路(第二十四篇) 面向对象初级:多态、封装
一.多态 多态 多态:一类事物有多种形态,同一种事物的多种形态,动物分为鸡类,猪类.狗类 例子 import abc class H2o(metaclass=abc.ABCMeta): def _ ...
- Python之路(第二十二篇) 面向对象初级:概念、类属性
一.面向对象概念 1. "面向对象(OOP)"是什么? 简单点说,“面向对象”是一种编程范式,而编程范式是按照不同的编程特点总结出来的编程方式.俗话说,条条大路通罗马,也就说我们使 ...
- 第二十二篇、IO多路复用 一
一.简介io多路复用 可以监听多个文件描述符(socket对象)(文件句柄),一旦文件句柄出现变化,就会感知到 Linux中的 select,poll,epoll(内核2.6以上) 都是IO多路复用的 ...
随机推荐
- Oracle Database Link 的创建和使用小见
假设:需要从数据库db_a通过db_link连接到db_b查询数据库b的部分相关信息 前提条件: 数据库a账户需要有创建dblink的权限,如果没有可以使用dba账户赋权限 grant CREATE ...
- 从C转到JAVA学习路之struct与class对比(转)
转自:http://blog.csdn.net/andywxf01/article/details/53506549 JAVA里最牛B的最基本的就是类,而C语言中的struct也可以定义自己的数据结构 ...
- 转: ios学习入门进阶
著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:利炳根链接:https://www.zhihu.com/question/19627420/answer/45962351来源 ...
- hdu1698 Just a Hook (线段树区间更新 懒惰标记)
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- hdu1236 排名(结构体排序)
排名 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submiss ...
- React Native Android入门实战及深入源代码分析系列(2)——React Native源代码编译
本文为老曾原创.转载需注明出处:viewmode=contents">http://blog.csdn.net/minimicall?viewmode=contents 在上一节中,我 ...
- TFTP 与 FTP的区别
FTP(File Transfer Protocol,文件传输协议)协议在TCP/IP协议族中属于应用层协议,用于在远端服务器和本地客户端之间传输文件,使用TCP端口20和21进行传输.端口20用于传 ...
- 自己动手开发更好用的markdown编辑器-07(扩展语法)
这里文章都是从个人的github博客直接复制过来的,排版可能有点乱. 原始地址 http://benq.im/2015/05/19/hexomd-07/ 文章目录 1. 准备工作 2. 目录语法 ...
- SpringCloud系列六:Eureka的自我保护模式、IP选择、健康检查
1. 回顾 前面讲了很多Eureka的用法,比如Eureka Server.Eureka Server的高可用.Eureka Server的用户认证(虽然未完全实现).元数据等, 这章将讲解剩下的自我 ...
- FileNotFoundException: http:\localhos46087125.jpg (文件名、目录名或卷标语法不正确
java.io.FileNotFoundException: http:\localhost:8080\ipms\upload\1332146087125.jpg (文件名.目录名或卷标语法不正确.) ...