一:先说虚拟函数的静态决议(Static Resolution)

  在两种情况下,虚拟函数机制不会出现预期行为:1、在基类的constructor和destructor内;2、当我们使用的是基类的对象,而非基类对象的pointer 或 reference时。

  上述第二种情况很好理解,第二种情况是C++多态机制的重要概念。第一种情况其实也很简单,但我才刚开始学习C++,怕以后自己会不小心把一些虚函数写在constructor 或 destructor里,固写此文章记录一下,下面给出第一种情况的解释:

  -----------------摘抄Essential C++解释开始-----------------

  当我们构造派生类对象时,基类的constructor会先被调用。如果在基类的constructor中调用某个虚拟函数,会发生什么事?调用的应该是派生类所定义的那一份吗?

  问题出在此刻派生类中的data member尚未初始化。如果此时调用派生类的那一份虚拟函数,它便有可能取用未经初始化的data members,这可不是一件好事。

  基于这个理由,在基类的constructor中,派生类的虚拟函数绝对不会被调用。同理,如果在基类的destructor中调用虚拟函数,此规则同样成立。

  -----------------摘抄Essential C++解释结束-----------------

举例:

  基类代码

  

 1 #pragma once 2 #include <typeinfo> 3 #include <iostream> 4 class num_sequence 5 { 6 public: 7     num_sequence(void); 8     virtual const char* what_am_i() const; 9     virtual void display() const { std::cout << "Based decontroctor" << std::endl; }10     virtual ~num_sequence(void) { display(); }11 };

  派生类代码

  

 1 #pragma once 2 #include "num_sequence.h" 3  4 class Fibonacci : 5     public num_sequence 6 { 7 public: 8     Fibonacci(void); 9     virtual void display() const { std::cout << "Drived destructor" << std::endl; }10     ~Fibonacci(void) { display(); };11     void testTypeId() { std::cout << "testTypeIdFunction" << std::endl; }12 };

然后在main里测试:

  Fibonacci fib;
  num_sequence *ps = &fib;

输出的结果是:

  Derived destructor
  Based destructor
  请按任意键继续. . .

即:分别调用子类和基类的析构函数(调用基类的析构函数时,基类析构函数里的display()函数没有动态执行子类的display())

二:RTTI

  基类num_sequence.cpp中加入

inline const char* num_sequence::what_am_i() const{return typeid( *this ).name();}

主main程序里面:

  

 1 Fibonacci fib; 2 num_sequence *ps = &fib; 3  4 if ( typeid(*ps) == typeid(Fibonacci) ) 5 { 6     ps->Fibonacci::testTypeId(); // 错误 7     ps->testTypeId();// 错误 8     if ( Fibonacci *pf = dynamic_cast<Fibonacci*> (ps) ) 9     {10         pf->testTypeId();11     }12 }

  Line6、Line7错误,这里ps并不"知道"它所寻址的对象实际上是什么型别--纵使我们知道,typeid及虚拟函数机制也知道。。

  为了调用Fibonacci所定义的testTypeId(),我们必须指示编译器,将ps的型别转换为Fibonacci指针。

  1、static_cast可以转换:Fibonacci *pf = static_cast<Fibonacci*>( ps );

  但存在危险,因为编译器无法确认我们所进行的转换操作是否完全正确。

  2、dynamic_cast:这是一个RTTI运算法,会进行执行期检验操作,检验ps所指对象是否属于Fibonacci类。如果是,转换操作便会发生,于是pf便指向该Fibonacci对象。如果不是,dynamic_cast运算符返回0。

转载于:https://www.cnblogs.com/ziyoudefeng/archive/2012/03/20/2407907.html

虚拟函数的静态决议 和 RTTI 小例子相关推荐

  1. php函数的默认值,php函数指定默认值方法的小例子

    php函数指定默认值方法的小例子 本节内容: php函数指定默认值 在php编程中,为自定义函数设定默认值,当用户调用该函数时,如果不给参数指定值,参数会用默认值顶替. 例1, 复制代码 代码如下: ...

  2. 虚拟函数-1、静态联编与动态联编,引入虚函数

    在实际开发工作中,为提高代码的重用性,编写通用的功能模块,往往需要设计处理几种不同对象的通用程序,如示例2.1所示. 示例清单2.1 #include "stdio.h" #inc ...

  3. 虚拟函数是否应该被声明仅为private/protected?

    问题导入  我想对于大家来说,虚拟函数并不能算是个陌生的概念吧.至于怎么样使用它,大部分人都会告诉我:通过在子类中重写(override)基类中的虚拟函数,就可以达到OO中的一个重要特性--多态(po ...

  4. 虚拟函数-2、实现机制

    讲到这里,也许读者对虚拟函数还不能有一个清晰的认识.下面就对虚拟函数的实现机制作简要介绍. 2.3.1 类和对象的内存分配机制 首先应该了解类及对象的内存分配机制.如果有类的定义如下: class C ...

  5. php 函数静态变量,php 函数中静态变量使用的问题实例分析

    本文实例讲述了php 函数中静态变量使用的问题.分享给大家供大家参考,具体如下: function msg() { static $a = 0; echo $a++, ' '; } msg(); ms ...

  6. 初等数论--同余--欧拉函数、欧拉定理、费马小定理

    初等数论--同余--欧拉函数.欧拉定理.费马小定理 概念 同余类,既约同余类 欧拉函数 完全剩余系,既约剩余系 关于完全剩余系.既约剩余系一些比较简单的定理 欧拉定理.费马小定理 博主是初学初等数论( ...

  7. java中所有函数都是虚函数_关于Java:虚拟函数与纯虚函数之间的区别是什么?...

    本问题已经有最佳答案,请猛点这里访问. Possible Duplicate: C++ Virtual/Pure Virtual Explained 虚函数和纯虚函数有什么区别? CPP中的纯虚函数与 ...

  8. python open函数_精选2个小例子,带你快速入门Python文件处理

    阅读本文大概需要7分钟讲完了函数和模块,我们来讲一讲文件的使用,python对数据的处理分两种一种是本地文件的处理,另外一种是通过网络数据处理(也就是爬虫相关的).而本地的数据处理,主要是通过文件的读 ...

  9. C++结构体中定义虚拟函数

    C++结构体中定义虚拟函数 C++中一个结构体可以包含函数(这个函数在C++我们通常中称为成员函数),C++中的结构体体现了数据结构和算法的结合.类可以从结构体继承.如下列示例: #ifndef PU ...

最新文章

  1. css position的父级,css position absolute 相对于父元素的设置方式
  2. 拯救顽疾大作战!IDC绘中国医疗AI生态图谱,英伟达献医疗影像新杀器
  3. stm32跑python-STM32F4系列使用MicroPython开发
  4. input上传文件个数控制
  5. MySQL左关联、右关联、内关联查询
  6. 普林斯顿大学英伟达Facebook提出基于深度神经网络的全动态推理,助力轻量级网络!...
  7. A 服务器上运行B 服务器上可以正常运行的程序出现问题
  8. Open Graph Protocol(开放内容协议)
  9. 百度语义预训练ERNIE实现物流信息抽取任务
  10. oracle ORA-00054 资源正忙
  11. fastReport 绑定DataBand数据源后还是打印出一条数据
  12. 10年专注单片机从业者告诉你如何自制一个属于自己的单片机开发板
  13. 李氏第二法分析稳定性matlab,9-4李雅普诺夫稳定性分析2010.ppt
  14. 记账系统推荐金蝶精斗云_金蝶精斗云云进销存软件哪款比较好?
  15. 《编程珠玑》-- 开篇:BitMap算法用于磁盘文件排序的原理与实现
  16. 大话设计模式之爱你一万年:第三章 创建型模式:工厂模式:我想让你坐在宝马里笑:6.工厂模式在Spring框架和JDK源码中的应用
  17. Download EditPlus Text Editor
  18. Python实现图像的全景拼接,这不比ps牛逼
  19. 为你推荐10款开发常用的代码编辑器
  20. OS实战笔记(4)-- 虚拟地址和物理地址的转换

热门文章

  1. java pdf水印排布问题_Java实现pdf文件添加水印,铺满全页。
  2. 【ORACLE】20道Oracle运维常见面试题
  3. java map套arraylist,在Java中的HashMap和ArrayList的区别?
  4. 韵达基于云原生的业务中台建设 | 实战派
  5. Kubernetes 与 OpenYurt 无缝转换(命令式)
  6. 为什么说 Serverless 引领云的下一个十年?
  7. 宁波大学计算机专业英语面试的形式,宁波大学信息学院计算机网络2014复试试题(回忆版)...
  8. python可抓取数据包括什么_Python对JS型数据抓取有什么特别好的方法吗,pythonjs型抓取,想写一个爬虫,但是需要抓...
  9. wireshark合并多个文件_小技巧:快速合并多个excel文件(收藏版)
  10. 华为mate40计算机,原来拍摄还能这么玩?华为Mate40 Pro连接电脑+耳机,Vlog输出分分钟...