博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
第二十二篇:C++中的多态机制
阅读量:6445 次
发布时间:2019-06-23

本文共 2195 字,大约阅读时间需要 7 分钟。

前言

       封装性,继承性,多态性是面向对象语言的三大特性。其中封装,继承好理解,而多态的概念让许多初学者感到困惑。本文将讲述C++中多态的概念以及多态的实现机制。

什么是多态?

       多态就是多种形态,就是许多情况下可以互换地使用基类型和派生类型的多种形态。

多态的实现

       依赖于动态绑定机制。

动态绑定机制相关

       动态绑定是函数实际参数和形式参数绑定的一种方式,它是指我们能够在函数接口中使用继承层次中任意类型的对象,无需关心对象的具体类型。

       动态执行接口函数的对象参数的哪个函数得在程序实际执行的时候才能确定

       C++中默认不使用动态绑定,要触发动态绑定必须满足两个条件:

       1. 接口函数的形式参数必须是引用类型或者指针类型。

       2. 动态执行函数(对象参数的成员函数而非接口函数)必须是声明为虚成员函数。

代码实例一

       下面代码创建基类对象a,然后创建其派生对象b,当将a,b作为参数传入函数printNum()后,函数让它们分别调用自己的函数getNum():

1 #include 
2 3 using namespace std; 4 5 // 基类 6 class A { 7 public: 8 A() {a=0;} 9 // **需要动态执行的函数必须声明为虚函数,满足了上条件2。10 virtual int getNum() {11 return a;12 }13 private:14 int a;15 };16 17 // 派生类18 class B : public A {19 public:20 B() {b=1;}21 // 基类中已经声明过为虚函数了不需要再次声明22 int getNum() {23 return b;24 }25 private:26 int b;27 };28 29 // **接口函数形参声明为引用类型,满足了上条件1。30 void printNum(A & a) {31 // 当实参为基类对象则调用基类对象的getNum,实参为派生类对象则调用派生类对象的getNum。32 cout << a.getNum() << endl;33 }34 35 int main()36 {37 A a;38 B b;39 40 printNum(a);41 printNum(b);42 43 return 0;44 }

       运行结果:

       

       可以观察到顺利实现了动态绑定,a b分别执行自己的getNum() 函数。

代码实例二

  下面代码同样创建基类对象a,然后创建其派生对象b,当将a,b作为参数传入函数printNum()后,函数让它们分别调用自己的函数getNum()(但本例接口函数的形式参数改成了值类型 ):

1 #include 
2 3 using namespace std; 4 5 // 基类 6 class A { 7 public: 8 A() {a=0;} 9 // **需要动态执行的函数必须声明为虚函数,满足了上条件2。10 virtual int getNum() {11 return a;12 }13 private:14 int a;15 };16 17 // 派生类18 class B : public A {19 public:20 B() {b=1;}21 // 基类中已经声明过为虚函数了不需要再次声明22 int getNum() {23 return b;24 }25 private:26 int b;27 };28 29 // **接口函数形参声明为值类型,不满足上条件1。30 void printNum(A a) {31 // 未有实现动态绑定,因此不论实参是何种类型,均执行基类的getNum()函数。 32 cout << a.getNum() << endl;33 }34 35 int main()36 {37 A a;38 B b;39 40 printNum(a);41 printNum(b);42 43 return 0;44 }

       运行结果:

       

       可以观察到没有实现动态绑定,a b都执行a的getNum() 函数。这意味着,对象本身并不支持多态,它刚进入函数就被彻底地转换成了形参类型。因此,实现多态要靠的是对象的指针或者引用,而不是对象本身。这也是《C++ Primer》一书中不断强调的东西。

说明

       1. 派生类和基类的虚函数类型要一致,只有一种例外 --- 返回对基类类型的引用的虚函数。派生类中的虚函数可以返回基类函数所返回类型的派生类的引用。

       2. 基类和派生类的虚函数的默认实参要相同,不然会引起混淆。

小结

       封装保证了类的重用( 安全方面 ),继承实现了类的重用,多态则实现了接口的重用。这三个机制体现了C++代码的可重用性,反映了C++在处理大型程序的优势。

转载地址:http://gdpwo.baihongyu.com/

你可能感兴趣的文章
关于mac远程链接window服务器以及实现共享文件
查看>>
angular的service与factory
查看>>
Redis慢查询,redis-cli,redis-benchmark,info
查看>>
新建MVC3 编译出现 System.Web.Mvc.ModelClientValidationRule
查看>>
mysql主从同步从库同步报错
查看>>
Virtualbox 虚拟机网络不通
查看>>
poj 1017 Packets 贪心
查看>>
java概念基础笔记整理
查看>>
play music
查看>>
self parent $this关键字分析--PHP
查看>>
CC_UNUSED_PARAM 宏含义的解释
查看>>
leetcode124二叉树最大路径和
查看>>
设计模式——中介者模式
查看>>
VI常用命令和按键
查看>>
AngularJS笔记整理 内置指令与自定义指令
查看>>
学习OpenCV——BOW特征提取函数(特征点篇)
查看>>
shell与正则表达式
查看>>
第三篇:白话tornado源码之请求来了
查看>>
10分钟搞定支付宝和微信支付的各种填坑
查看>>
IntelliJ Idea 集成svn 和使用
查看>>