C++多态性的浅析
多态性是C++的一个重要特性,【不扯淡直接进入正题】
灵活运用多态,首先得知道类之间的继承。 当B继承了A类后,一般都是公有继承。 B的实例化对象的内存空间结构若是了解 就可以合理利用多态了。
A的内存空间我们假定为a,
B的内存空间是这样的结构: a
b新增的地址空间
a+b 就是B实例化对象的地址空间了。
在类的空间里面 都会有虚函数的信息表,【没有虚函数 就没法考虑多态】;A有A的虚函数信息表,B有B的虚函数信息表。
结合下面例子来理解: class A{public: void fun1(){ printf(”A1\n");} virtual void fun2(){printf ("A2\n");} };
class B :public A{ public:void fun1(){ printf(”B1\n");} void fun2(){printf("B2\n");} };
int main()
{
A a; B b;
A* p = &a;
p->fun2();
p = &b;
p-> fun2();
p->fun1();
}
fun2 为虚函数, 第一个输出全在A 里面。跟B 没有关系。 第二个输出解释: p是A类的指针,其寻址空间大小跟A类对象空间大小一致。
当把b的对象地址赋予其的时候。因为其寻址空间 上面已经说明。在其寻址fun2时候,发现其实虚函数,虚函数是运行时候加载的。此时编译器
根据其真实对象的虚函数来选择调用。这是编译器的约定,故而寻址到b的虚函数进行调用。
此时的 p->fun1(); 因为其寻址空间限制,调用的还是A的 fun1。
【有待验证】 题外: 上面的 B *p = &a; 的话 会出现什么结果呢? 解释: 此时p的寻址空间 就是 B对象的空间大小,此时把a对象地址赋予p时候,因为p寻址区间>a对象的内存空间。 会造成p在访问时候出现无效地址的访问,会造成内存错误,一般程序里面出现内存崩溃等情况 就这样。
【真心期待路过的老鸟或者有兴趣的朋友留言沟通,指正,谢谢】
延伸: 【
B *p = (B *)&a;
ptr->fun1();
ptr->fun2();
问这两调用的输出结果。这是一个用子类的指针去指向一个强制转换为子类地址的基类对象。结果,这两句调用的输出结果是B1,A2。
并不是很理解这种用法,从原理上来解释,由于B是子类指针,虽然被赋予了基类对象地址,但是ptr->foo()在调用的时候,由于地址偏移量固定,偏移量是子类对象的偏移量,于是即使在指向了一个基类对象的情况下,还是调用到了子类的函数,虽然可能从始到终都没有子类对象的实例化出现。
而ptr->fuu()的调用,可能还是因为多态性的原因,由于指向的是一个基类对象,通过虚函数列表的引用,找到了基类中foo()函数的地址,因此调用了基类的函数。由此可见多态性的强大,可以适应各种变化,不论指针是基类的还是子类的,都能找到正确的实现方法。】
C++多态性的浅析的更多相关文章
- [转载]C++虚函数浅析
原文:http://glgjing.github.io/blog/2015/01/03/c-plus-plus-xu-han-shu-qian-xi/ 感谢:单刀土豆 C++虚函数浅析 JAN 3RD ...
- 浅析JAVA设计模式之工厂模式(一)
1 工厂模式简单介绍 工厂模式的定义:简单地说,用来实例化对象,取代new操作. 工厂模式专门负责将大量有共同接口的类实例化.工作模式能够动态决定将哪一个类实例化.不用先知道每次要实例化哪一个类. 工 ...
- 浅析JAVA设计模式之工厂模式(二)
1 工厂方法模式简单介绍 工厂方法 (Factroy Method)模式:又称多态性工厂模式(Polymorphic Factory),在这样的模式中,核心工厂不再是一个详细的类.而是一个抽象工厂,提 ...
- Java基础之Collection与Collections浅析
Java基础之Collection与Collections浅析 一.前言: 位于Java.util包下的Collection与Collections都是Java中重要的工具类,它们都是Java集合框架 ...
- Java基础之多态和泛型浅析
Java基础之多态和泛型浅析 一.前言: 楼主看了许多资料后,算是对多态和泛型有了一些浅显的理解,这里做一简单总结 二.什么是多态? 多态(Polymorphism)按字面的意思就是“多种状态”.在面 ...
- SQL Server on Linux 理由浅析
SQL Server on Linux 理由浅析 今天的爆炸性新闻<SQL Server on Linux>基本上在各大科技媒体上刷屏了 大家看到这个新闻都觉得非常震精,而美股,今天微软开 ...
- 【深入浅出jQuery】源码浅析--整体架构
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- 高性能IO模型浅析
高性能IO模型浅析 服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种: (1)同步阻塞IO(Blocking IO):即传统的IO模型. (2)同步非阻塞IO(Non-blocking ...
- javaScript的原型继承与多态性
1.prototype 我们可以简单的把prototype看做是一个模版,新创建的自定义对象都是这个模版(prototype)的一个拷贝 (实际上不是拷贝而是链接,只不过这种链接是不可见,给人们的感觉 ...
随机推荐
- [技巧]把Excel里的数据插入到数据库里的方法
.如果先在6行数据的最后一列在插入一列数据,请先把列名写好,然后再第一行的该列下输入数字, 然后选中该单元格向下拖拽一个单元格然后就能看到黑色的小框, 双击右下角黑色的小点,6行数据就 会填上默认的第 ...
- framMaker、Velocity模版引擎
1.一种模板文件,可以自动加载数据到模板里面展现. 类似:Velocity 2.使用场景 1.web开发模式 WEB-INF/view/vm 在互联网公司的开发都是基于vm的开发,其次就是使用JS的框 ...
- Arch Linux 修改主机名称
Hostname Set the hostname to your liking (e.g. arch): # echo myhostname > /etc/hostname Add the s ...
- archlinux log 文件查看
# pacman -S gnome-system-log gnome-logsextra/gnome-logs 3.12.1-1 (gnome-extra) A log viewer for the ...
- history.back(-1)和history.go(-1)的区别
history.back(-1):直接返回当前页的上一页,数据全部消息,是个新页面 history.go(-1):也是返回当前页的上一页,不过表单里的数据全部还在 返回到指定连接:document.l ...
- js中字符串的截取
当需要从一组数据中移除到符合条件的某一个数据的时候,在这种情况下如何进行截取呢? 基本思路: ①将其通过特定的符号,将一组字符串进行拼接,或者用","或者用"+" ...
- php操作mysql的基础链接实例
- AS3深拷贝数据对象(2)深拷贝VO对象
Topic:对于用户自定义的VO对象进行深拷贝,一种VO对象的某属性可能是另一种VO对象的实例. 方法1:通过传说中的“AS3隐藏特性——ByteArray.writeObject和readObjec ...
- 延迟jquery,ready事件触发的时间
$.holdReady(true);//holdReady必须在ready()方法调用之前来调用,来延迟ready()方法的执行 $(document).ready(function(){ conso ...
- play framework 框架安装及myeclipse 导入项目
下载 play framework 框架. 解压你你要解压的目录 E:\play-1.2.7 相对其他的WEB框架.play的配置是相当简单的.没有那么多配置文件的搞法.上手比较快,就是相关的资料比较 ...