前言

封装性,继承性,多态性是面向对象语言的三大特性。其中封装,继承好理解,而多态的概念让许多初学者感到困惑。本文将讲述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++中的多态机制的更多相关文章

  1. Python开发【第二十二篇】:Web框架之Django【进阶】

    Python开发[第二十二篇]:Web框架之Django[进阶]   猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...

  2. Android UI开发第二十八篇——Fragment中使用左右滑动菜单

    Fragment实现了Android UI的分片管理,尤其在平板开发中,好处多多.这一篇将借助Android UI开发第二十六篇——Fragment间的通信. Android UI开发第二十七篇——实 ...

  3. Python之路【第二十二篇】:Django之Model操作

    Django之Model操作   一.字段 AutoField(Field) - int自增列,必须填入参数 primary_key=True BigAutoField(AutoField) - bi ...

  4. 【Python之路】第二十二篇--Django【基础篇】

    1 Django流程介绍 MTV模式       著名的MVC模式:所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层:他们之间以一种插件似的,松耦合的方式连接在一起. 模型负责业 ...

  5. 第二十二篇:在SOUI中使用代码向窗口中插入子窗口

    使用SOUI开发客户端UI程序,通常也推荐使用XML代码来创建窗口,这样创建的窗口使用方便,当窗口大小改变时,内部的子窗口也更容易协同变化. 但是最近不断有网友咨询如何使用代码来创建SOUI子窗口,特 ...

  6. 【第二十二篇】从客户端中检测到有潜在危险的 Request.Form 值

    提交数据的时候  用js的方法   escape(富文本框的值)    例:escape(UM.getEditor('Content').getContent()); 取值的时候   unescape ...

  7. Python之路(第二十四篇) 面向对象初级:多态、封装

    一.多态 多态 多态:一类事物有多种形态,同一种事物的多种形态,动物分为鸡类,猪类.狗类 例子 import abc class H2o(metaclass=abc.ABCMeta): ​ def _ ...

  8. Python之路(第二十二篇) 面向对象初级:概念、类属性

    一.面向对象概念 1. "面向对象(OOP)"是什么? 简单点说,“面向对象”是一种编程范式,而编程范式是按照不同的编程特点总结出来的编程方式.俗话说,条条大路通罗马,也就说我们使 ...

  9. 第二十二篇、IO多路复用 一

    一.简介io多路复用 可以监听多个文件描述符(socket对象)(文件句柄),一旦文件句柄出现变化,就会感知到 Linux中的 select,poll,epoll(内核2.6以上) 都是IO多路复用的 ...

随机推荐

  1. 解决Linux关闭终端(关闭SSH等)后运行的程序或者服务自动停止【后台运行程序】

    问题描述:当SSH远程连接到服务器上,然后运行一个服务 ./catalina.sh start,然后把终端开闭(切断SSH连接)之后,发现该服务中断,导致网页无法访问.   解决方法:使用nohup命 ...

  2. python对solr进行查询、插入操作(GET\POST)

    循环查询一个列表中词的个数: #coding=utf-8 import requests ls = [u'我', u'是', u'一个', u'天才', u'你', u'也是'] for item i ...

  3. jQuery--百度百科

    JQuery是继prototype之后又一个优秀的Javascript库.它是轻量级的js库 ,它兼容CSS3,还兼容各种浏览器(IE 6.0+, FF 1.5+, Safari 2.0+, Oper ...

  4. 理解shell中的atime,mtime,ctime

    所有文件都有3个时间信息,保存在文件系统中 atime (Access time)是文件最后一此读的时间 或者执行文件的时间 mtime (Modified time)是文件最后一次写的时间(是在写入 ...

  5. NSight统计数据的颜色,缩写意义是什么?来自NV Jeff Kiel 比较官方的解释!

    结合这个图示来看:https://dl.dropboxusercontent.com/u/32077444/nsight.pdf 1) The bars you see in the Summary ...

  6. CoolHash数据库引擎压测对比报告

    Coolhash 当前性能指标:读写吞吐量超过百万,千万级别查询1秒完成,连续48小时打满CPU强压力运行稳定.redis官方公布读写性能在10万 tps,leveldb官方公布写性能在40万tps, ...

  7. [1-3] 把时间当做朋友(李笑来)Chapter 3 【提高心智,和时间做朋友】 摘录

    1. 精确感知时间 我有个朋友叫做时间.她跟我真可算作两小无猜,默默陪了二十多年我才开始真正认识她.她原本没有面孔,却因为我总是用文字为她拍照,而因此可以时常伴我左右.她原本无情,我却可以把她当作朋友 ...

  8. jquery ajax 脑图

  9. GEEK学习笔记— —程序猿面试宝典笔记(三)

    所谓笔记,就是比較个人的东西,把个人认为有点意思的东西记录下来~~ 程序猿面试宝典笔记(一)基本概念 程序猿面试宝典笔记(二)预处理.const和sizeof 程序猿面试宝典笔记(三)auto_ptr ...

  10. Atitit.虚拟机与指令系统的设计

    Atitit.虚拟机与指令系统的设计 1. 两种计算模型  ,堆栈机和状态机(基于寄存器的虚拟机1 1.1.1. 堆栈机1 1.1.2. 状态机2 2. 为什么状态机比堆栈机快呢?3 2.1. Sta ...