本文通过简单例子说明子类之间发生强制转换时虚函数如何调用,旨在对c++继承中的虚函数表的作用机制有更深入的理解。

#include<iostream>
using namespace std; class Base
{
public:
virtual void f()
{
cout<<"Base::f()"<<endl;
}
}; class child1:public Base
{
public:
virtual void f()
{
cout<<"child1::f()"<<endl;
} virtual void a()
{
cout<<"child1::a()"<<endl;
}
}; class child2:public Base
{
public:
virtual void f()
{
cout<<"child2::f()"<<endl;
} virtual void b()
{
cout<<"child2::b()"<<endl;
} virtual void a()
{
cout<<"child2::a()"<<endl;
}
}; int main()
{ child1 c1;
child2* pc21=(child2*)&c1;
pc21->b();//输出 child1::a()
// pc21->a();//访问越界,程序运行时崩溃
child2 c2;
child1* pc12=(child1*)&c2;
pc12->a();//输出 child2::b()
return ;
}

结论:

  1、通常的类型强转是告诉编译器必须按照指定结构的内存布局来解析对应内存,如上例中“child2* pc21=(child2*)&c1; ”,编译器会把c1对应的内存来当做类child2的内存布局来解析。因为在类child2的虚函数表中,共存在三个函数,分别为f() b() a(),其中函数b()是第二个,因此编译器就会把对象c1对应的内存来当做类child2的内存布局来解析(注意内存里的内容不变,还是c1的,即为类child1的内存布局,在这里只有虚函数表),此时在类child1的虚函数表中也找第二个函数,找到了函数a(),因此输出“child1::a()”,运行正常。但这种行为可能是危险的,若使用的内存布局并不适合真实内存,很可能造成访问越界等问题(如上例中的“pc21->a();”,这次就在类B的虚函数表中找第三个函数,结果没有找到(访问越界),函数运行时崩溃。),因此使用强制转换操作时应特别注意。

  2、通过上述例子可知,虚函数在虚函数表中的存储顺序是与声明顺序一致的,而不是虚函数名字的字符串排序,如本例中为f() b() a(),虽然编程时的自动补全提示框中显示的顺序是a() b() f(),但可能已经经过内部优化,这个就不太清楚了(也不是我们要研究的内容)。

c++ 继承类强制转换时的虚函数表工作原理的更多相关文章

  1. C++ 类的存储方式以及虚函数表

    一.C++成员函数在内存中的存储方式 用类去定义对象时,系统会为每一个对象分配存储空间.如果一个类包括了数据和函数,要分别为数据和函数的代码分配存储空间.按理说,如果用同一个类定义了10个对象,那么就 ...

  2. C++ 类中有虚函数(虚函数表)时 内存分布

    虚函数表 对C++ 了解的人都应该知道虚函数(Virtual Function)是通过一张虚函数表(Virtual Table)来实现的.简称为V-Table.在这个表中,主是要一个类的虚函数的地址表 ...

  3. C++ 虚函数表解析 继承

    C++ 虚函数表解析 陈皓 http://blog.csdn.net/haoel 前言 C++中的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父 ...

  4. vs查看虚函数表和类内存布局

    虚继承和虚基类 虚继承:在继承定义中包含了virtual关键字的继承关系:     虚基类:在虚继承体系中的通过virtual继承而来的基类,需要注意的是:class CSubClass : publ ...

  5. C++多态中虚函数表合并与继承问题

    多态: C++的多态是通过一张虚函数表(Virtual Table)来实现的,简称为 V-Table.在这个表中,主要是一个类的虚函数的地址表,这张表解决了继承.覆写的问题,保证其真实反应实际的函数. ...

  6. C++ 虚函数表解析

    转载:陈皓 http://blog.csdn.net/haoel 前言 C++中 的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指向其子类的实例,然后通过父类的指针调用实 ...

  7. C++虚函数表原理

    C++中的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型别的指针指 向其子类的实例,然后通过父类的指针调用实际子类的成员函数.这种技术可以让父类的指针有“多种形态”,这是一种泛型技 ...

  8. C++ 虚函数表解析(转载)

    转载自:陈皓 http://blog.csdn.net/haoel/article/details/1948051/ 前言 C++中的虚函数的作用主要是实现了多态的机制.关于多态,简而言之就是用父类型 ...

  9. 转载:C++ 虚函数表解析

    目录(?)[+]   转载:http://blog.csdn.net/haoel/article/details/1948051# 前言 C++中 的虚函数的作用主要是实现了多态的机制.关于多态,简而 ...

随机推荐

  1. spring中依赖注入与aop讲解

    一.依赖注入 这个属于IOC依赖注入,也叫控制反转,IOC是说类的实例由容器产生,而不是我们用new的方式创建实例,控制端发生了改变所以叫控制反转. 1 2 3 4 5 6 7 8 9 10 11 1 ...

  2. php中使用mysql_fetch_object向页面输出结果,总结!

    public function selectResultByThird() { if ((!empty ($_REQUEST["bigname"])) && (!e ...

  3. Android SQLITE数据类型

    2011-6-24 15:14:00来源:Sql   SQLITE数据类型 SQLite与其他常见的DBMS的最大不同是它对数据类型的支持.其他常见的DBMS通常支持强类型的数据,也就是每一列的类型都 ...

  4. mysql root密码

    方法1: 用SET PASSWORD命令 首先登录MySQL. 格式:mysql> set password for 用户名@localhost = password('新密码'); 例子:my ...

  5. sqlite3API函数

    回顾: DDL 表的创建.修改.删除 create table 表名(字段名 字段类型 [约束],...); alter table 表名 {rename to 新名字 | add column 字段 ...

  6. spring mvc自定义注解--登录时密码加密注解

    1,定义注解名称接口 /** * 使用该注解不用再MD5转换了 * * @author adonis * */ @Target(ElementType.PARAMETER) @Retention(Re ...

  7. KNN算法--物以类聚,人以群分

    KNN(K Nearest Neighbors,K近邻 )算法是机器学习所有算法中理论最简单,最好理解的.KNN是一种基于实例的学习,通过计算新数据与训练数据特征值之间的距离,然后选取K(K>= ...

  8. AFNetWorking 之 Get/Post 请求的使用

    1. Get 与 Post 比较 GET请求:简单业务.明文发送 POST请求:上传文件,重要信息.加密信息,.大数据信息. 2. 序列化 默认是JSon格式. // 请求的序列化 manager.r ...

  9. delphi字符串操作函数一览

    首部 function SameText(const S1, S2: string): Boolean; $[SysUtils.pas 功能 返回两个字符串是否相等 说明 不区分大小写 参考 < ...

  10. %c输入应注意的问题

    for(i=0;i<n;i++) { getchar(); scanf("%c",&str[i]); } 这样输入是错的 的这样输入 for(i=0;i<n;i ...