本来是准备在工厂模式中顺便整理。但粗略浏览了,内容还是很多,需要单独开一篇。

一、什么是多态性?

  多态性可以概括为“一个接口,多种方法”。
  多态与非多态的区别在于“成员函数调用地址的早绑定和晚绑定”。“早绑定”在编译期就可以确定函数的调用地址,是静态的;“晚绑定”在运行时才能确定函数的调用地址,是动态的。
  多态的作用是什么呢?在面向对象的编程中,“封装”使得代码模块化;“继承”可以扩展以存在的代码;“多态”使得接口重用。

二、多态性的c++实现:虚函数

  声明基类的指针,该指针指向子类的对象。调用相应的虚函数时,可以根据子类的不同而调用不同的函数实现。因此有多态的三个条件:
    1)基类指针
    2)指向子类对象
    3)调用的是虚函数
  特殊的,对于强制类型转换,可以将子类对象的指针强制转化为基类对象的指针,
    1)当以基类对象的指针调用非虚函数时,仍然调用子类的函数实现
    2)当以基类对象的指针调用虚函数时,由于动态绑定,调用的是基类的函数的实现

三、虚函数的底层实现

  虚函数(Virtual Function)通过一张虚函数表(Virtual Table)来实现,主是要一个类的虚函数的地址表。在有虚函数的类的实例中保存了指向虚函数表的指针,并且指针存储的位置通常是实例的首地址。
  1、虚基类
    
    函数地址在表中的排列顺序同函数的声明顺序。
  2、当子类函数覆盖父类虚函数
     
    

    覆盖的函数f()位于父类虚函数f()的位置,其他函数排列不变。

四、虚函数实例

class base
{
public:
virtual void f() {cout << "in base::f()" << endl;} //虚函数
void g() { cout << "in base::g()" << endl;} //非虚函数
}; class derive: public base
{
public:
virtual void f() {cout << "in derive::f()" << endl;} //覆盖
void g() {cout << "in derive::g()" << endl;} //重载
}; int main(int argc, char **argv)
{
base *b = new derive(); //基类指针指向派生类的实例
b->f(); //虚函数 动态绑定 调用派生类的函数
b->g(); //非虚函数 静态编译 调用基类的函数
}

最新文章

  1. C语言的fopen函数(文件操作/读写)
  2. UBUNTU 16.04 编译 OPENJDK8
  3. css3样式控制(鼠标滑过 显示标注信息)
  4. 非常好的javascript 代码
  5. html5 history api
  6. 十步图解CSS的position
  7. 【转载】让windows使用linux系统的命令
  8. 获取和设置tinyMCE 4编辑器的内容
  9. 设置一个View的背景图片的集中方法
  10. Poj 1503 Integer Inquiry
  11. Flexigrid折行显示问题
  12. Redis跟Spring整合,sentinel模式
  13. scheme深拷贝和浅拷贝探索
  14. 【python】多进程共享变量Manager
  15. 【转载】DQL、DML、DDL、DCL的概念与区别
  16. 开放系统的直连式存储(Direct-Attached Storage,简称DAS)
  17. Python&#160;基于Python实现批量创建目录
  18. Python 零基础 快速入门 趣味教程 (咪博士 海龟绘图 turtle) 4. 函数
  19. div包裹页面后多余部分没有显示,也没滚动条 overflow 属性设置
  20. 判断一个点在多边形的内部C++

热门文章

  1. 基于JQ的多选/全选/反选及获取选中的值
  2. Mybatis相关SQL操作总结
  3. poj 3539 Elevator——同余类bfs
  4. Azure SLB + httpd + ILB + HAProxy + Atlas + MySQL
  5. Day2-VIM(二):插入
  6. throw和throws的区别和联系
  7. 隔行变色---bai
  8. vBulletin 5.x 版本通杀远程代码执行漏洞复现
  9. java反射专题三
  10. ios AppStore 帐号申请