虚拟函数的静态决议 和 RTTI 小例子
一:先说虚拟函数的静态决议(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 小例子相关推荐
- php函数的默认值,php函数指定默认值方法的小例子
php函数指定默认值方法的小例子 本节内容: php函数指定默认值 在php编程中,为自定义函数设定默认值,当用户调用该函数时,如果不给参数指定值,参数会用默认值顶替. 例1, 复制代码 代码如下: ...
- 虚拟函数-1、静态联编与动态联编,引入虚函数
在实际开发工作中,为提高代码的重用性,编写通用的功能模块,往往需要设计处理几种不同对象的通用程序,如示例2.1所示. 示例清单2.1 #include "stdio.h" #inc ...
- 虚拟函数是否应该被声明仅为private/protected?
问题导入 我想对于大家来说,虚拟函数并不能算是个陌生的概念吧.至于怎么样使用它,大部分人都会告诉我:通过在子类中重写(override)基类中的虚拟函数,就可以达到OO中的一个重要特性--多态(po ...
- 虚拟函数-2、实现机制
讲到这里,也许读者对虚拟函数还不能有一个清晰的认识.下面就对虚拟函数的实现机制作简要介绍. 2.3.1 类和对象的内存分配机制 首先应该了解类及对象的内存分配机制.如果有类的定义如下: class C ...
- php 函数静态变量,php 函数中静态变量使用的问题实例分析
本文实例讲述了php 函数中静态变量使用的问题.分享给大家供大家参考,具体如下: function msg() { static $a = 0; echo $a++, ' '; } msg(); ms ...
- 初等数论--同余--欧拉函数、欧拉定理、费马小定理
初等数论--同余--欧拉函数.欧拉定理.费马小定理 概念 同余类,既约同余类 欧拉函数 完全剩余系,既约剩余系 关于完全剩余系.既约剩余系一些比较简单的定理 欧拉定理.费马小定理 博主是初学初等数论( ...
- java中所有函数都是虚函数_关于Java:虚拟函数与纯虚函数之间的区别是什么?...
本问题已经有最佳答案,请猛点这里访问. Possible Duplicate: C++ Virtual/Pure Virtual Explained 虚函数和纯虚函数有什么区别? CPP中的纯虚函数与 ...
- python open函数_精选2个小例子,带你快速入门Python文件处理
阅读本文大概需要7分钟讲完了函数和模块,我们来讲一讲文件的使用,python对数据的处理分两种一种是本地文件的处理,另外一种是通过网络数据处理(也就是爬虫相关的).而本地的数据处理,主要是通过文件的读 ...
- C++结构体中定义虚拟函数
C++结构体中定义虚拟函数 C++中一个结构体可以包含函数(这个函数在C++我们通常中称为成员函数),C++中的结构体体现了数据结构和算法的结合.类可以从结构体继承.如下列示例: #ifndef PU ...
最新文章
- css position的父级,css position absolute 相对于父元素的设置方式
- 拯救顽疾大作战!IDC绘中国医疗AI生态图谱,英伟达献医疗影像新杀器
- stm32跑python-STM32F4系列使用MicroPython开发
- input上传文件个数控制
- MySQL左关联、右关联、内关联查询
- 普林斯顿大学英伟达Facebook提出基于深度神经网络的全动态推理,助力轻量级网络!...
- A 服务器上运行B 服务器上可以正常运行的程序出现问题
- Open Graph Protocol(开放内容协议)
- 百度语义预训练ERNIE实现物流信息抽取任务
- oracle ORA-00054 资源正忙
- fastReport 绑定DataBand数据源后还是打印出一条数据
- 10年专注单片机从业者告诉你如何自制一个属于自己的单片机开发板
- 李氏第二法分析稳定性matlab,9-4李雅普诺夫稳定性分析2010.ppt
- 记账系统推荐金蝶精斗云_金蝶精斗云云进销存软件哪款比较好?
- 《编程珠玑》-- 开篇:BitMap算法用于磁盘文件排序的原理与实现
- 大话设计模式之爱你一万年:第三章 创建型模式:工厂模式:我想让你坐在宝马里笑:6.工厂模式在Spring框架和JDK源码中的应用
- Download EditPlus Text Editor
- Python实现图像的全景拼接,这不比ps牛逼
- 为你推荐10款开发常用的代码编辑器
- OS实战笔记(4)-- 虚拟地址和物理地址的转换
热门文章
- java pdf水印排布问题_Java实现pdf文件添加水印,铺满全页。
- 【ORACLE】20道Oracle运维常见面试题
- java map套arraylist,在Java中的HashMap和ArrayList的区别?
- 韵达基于云原生的业务中台建设 | 实战派
- Kubernetes 与 OpenYurt 无缝转换(命令式)
- 为什么说 Serverless 引领云的下一个十年?
- 宁波大学计算机专业英语面试的形式,宁波大学信息学院计算机网络2014复试试题(回忆版)...
- python可抓取数据包括什么_Python对JS型数据抓取有什么特别好的方法吗,pythonjs型抓取,想写一个爬虫,但是需要抓...
- wireshark合并多个文件_小技巧:快速合并多个excel文件(收藏版)
- 华为mate40计算机,原来拍摄还能这么玩?华为Mate40 Pro连接电脑+耳机,Vlog输出分分钟...