C++对象模型(三)
来源:互联网 发布:知乎用户童谣诈骗事件 编辑:程序博客网 时间:2024/05/16 10:44
多重继承的数据成员布局
这里解释了这样的问题:当一个类从多个类继承时,并且这些类可能从其他类中继承的情况下,类的数据结构如何布局?
答案是,先将基类的成员依次排列,最后放本类的数据成员。
问题是有多个基类,这些基类的顺序是怎样的呢?C++标准并没有定义。但是一般来说,编译器会把先定义的基类的数据成员放在前面。
由此,写代码的时候,如果需要将派生类转换为基类类型时,必须注意以下两点:
1、 如果在派生类中,该基类成员排在所有数据最前面,则直接转换,不需要任何代价;
2、 如果在派生类中,该基类成员没有排在最前面,则编译器会自动转换,加上一定的位移。这样做是有代价的。
虚拟继承的数据成员布局
当一个类A继承自两个基类B、C,而B、C都继承自同一个父类D时,会遇到这样的问题:类A中可能有两个类D的对象。要解决这个问题,引入了虚拟继承的概念。
传统的解决方法是,编译器对每一个基类对象加一个指针。但是,如果继承链过长,会导致指针增多;且类对象的负担不能固定。
目前的编译器想到了很多解决的方法来解决这个问题。
微软用的方法是利用了virtual base class table,将虚拟基类的指针放在该表中,通过该表得到指针实现基类的访问。
Solaris的做法有些不一样。虽然也是用了virtual base class table,Solaris巧妙的使用了索引,正索引将访问到虚函数,而负索引则取到想要的虚拟基类的位移。注意是位移。
最后说明,基于以上的分析,取虚拟基类的数据成员代价是比较高的。最好声明的虚拟基类没有任何数据成员。
这里解释了这样的问题:当一个类从多个类继承时,并且这些类可能从其他类中继承的情况下,类的数据结构如何布局?
答案是,先将基类的成员依次排列,最后放本类的数据成员。
问题是有多个基类,这些基类的顺序是怎样的呢?C++标准并没有定义。但是一般来说,编译器会把先定义的基类的数据成员放在前面。
由此,写代码的时候,如果需要将派生类转换为基类类型时,必须注意以下两点:
1、 如果在派生类中,该基类成员排在所有数据最前面,则直接转换,不需要任何代价;
2、 如果在派生类中,该基类成员没有排在最前面,则编译器会自动转换,加上一定的位移。这样做是有代价的。
虚拟继承的数据成员布局
当一个类A继承自两个基类B、C,而B、C都继承自同一个父类D时,会遇到这样的问题:类A中可能有两个类D的对象。要解决这个问题,引入了虚拟继承的概念。
传统的解决方法是,编译器对每一个基类对象加一个指针。但是,如果继承链过长,会导致指针增多;且类对象的负担不能固定。
目前的编译器想到了很多解决的方法来解决这个问题。
微软用的方法是利用了virtual base class table,将虚拟基类的指针放在该表中,通过该表得到指针实现基类的访问。
Solaris的做法有些不一样。虽然也是用了virtual base class table,Solaris巧妙的使用了索引,正索引将访问到虚函数,而负索引则取到想要的虚拟基类的位移。注意是位移。
最后说明,基于以上的分析,取虚拟基类的数据成员代价是比较高的。最好声明的虚拟基类没有任何数据成员。
- C++对象模型(三)
- GIS面向对象模型设计(三)
- DHTML对象模型 (三)
- Objective-C对象模型
- Objective-C对象模型
- objective C 对象模型
- C ++ 对象模型
- Objective-C 对象模型
- 【C++】对象模型
- Objective-C对象模型
- C++对象模型-笔记三
- C++对象模型解析三
- DHTML对象模型(About the DHTML Object Model)(三)
- 深度探索C++对象模型之(三)
- 深度探索C++对象模型笔记(三)
- JavaScript 入门(三)BOM浏览器对象模型
- 深度探索C++对象模型(三)Data语意学
- 《深度探索C++对象模型》读书笔记(三)
- 链接器都干了些什么?
- 针对如"123456"之类的任意字符序列,输出它们所有的排列组合
- Ubuntu8.04 oracle10g安装
- 在编译GLib时 提示 GLib requires a 64 bit type 的解决办法
- 解读KeilC给C51程序自动添加的代码
- C++对象模型(三)
- Unix/Linux下C/C++开发技术概览
- C#中调用Windows API的要点
- 额。。。
- HTTP协议详解(真的很经典)
- MFC windows应用程序设计(一)——Windows 应用程序的基本概念
- 寻找失踪儿童:胡锦杨
- google docs api 文件标题乱码解决方法
- 读取Ini例子