虚函数的特性--内存结构的研究, 对象有虚表的反而多占内存了(多4字节即一个指针),函数是预告编译在代码区
2014-04-26 22:07
381 查看
http://blog.csdn.net/livelylittlefish/article/details/2171374
虚函数的应用特性
例:编写三个类:没有虚函数、有一个虚函数、有两个虚函数,在主函数中定义这三个类的对象,分别取这个类所占的内存空间的大小,观察在内存中的分配;
代码如下:
/************************************************************************
* 虚函数的应用特性例子
************************************************************************/
#include <iostream.h>
//没有虚函数的类
class CNoVirtual
{ int x;
public:
CNoVirtual(int nx){x=nx;}
void func() const{}
int GetX() const {return x;}
};
//有一个虚函数的类
class COneVirtual
{ int x;
public:
COneVirtual(int nx){x=nx;}
virtual void func() const{}
int GetX(){return x;}
};
//有两个虚函数的类
class CTwoCirtuals
{ int x;
public:
CTwoCirtuals(int nx){x=nx;}
virtual void func() const{}
virtual int GetX() const {return x;}
};
void main()
{ CNoVirtual obj1(100);
COneVirtual obj2(200);
CTwoCirtuals obj3(300);
cout<<"size of types: ";
cout<<"int : "<<sizeof(int)<<endl;
cout<<"CNoVirtual : "<<sizeof(CNoVirtual)<<endl;
cout<<"void* : "<<sizeof(void*)<<endl;
cout<<"COneVirtual : "<<sizeof(COneVirtual)<<endl;
cout<<"CTwoVirtual : "<<sizeof(CTwoCirtuals)<<endl;
}
1. 运行结果:
2. 对象的内存分配情况:
3. 对象的地址及内容:
4. 对象的成员变量的地址及内容:
综上,对象的内存空间分配情况如下:
说明:
从上面的结果可以看到,没有虚函数的类CNoVirtual的大小正好是其成员变量——一个整型数据的大小,而有一个虚函数和两个虚函数的类的大小还要加上一个紧缩的空指针类型的大小。这说明了在包含虚函数的类中,编译系统自动加入了一些表明类型的信息。
当一个类中拥有虚函数时,编译系统将为该类创建一个数组VTABLE。VTABLE数组中的元素是虚函数的地址,且同一虚函数的地址在基类和派生类的VTABLE中相对首位置的偏移是一样的。同时,编译系统还加入了相应的调用虚函数的代码。所有这些都是不需要程序员作的工作,由系统自动完成。在初始化该类对象时,将加入一个指向VTABLE的指针,这个指针一般称为VPTR。一般来说,VPTR位于该类对象的存储单元的最开始部位,如上图所示。
这样,当VPTR被正确的初始化之后,便指向了该对象的VTABLE,从而在对象及其特定的虚函数定义间建立了联系。从虚函数调用的意义上来说,VPTR表明了类型信息,因为它使得调用与类型相符合。
//类的函数已经编译好在代码区...根本不会算在sizeof()大小里面
//实际是有虚函数的类对象会多了个虚表的占用空间.
更多0
上一篇C++学习笔记(10)——虚基类的作用
下一篇C++学习笔记(12)——多态与虚函数
相关文章推荐
- 编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间。new(n)表示分配n个字节的内存空间。
- 请编写实现malloc()内存分配函数功能一样的代码。给出一个函数来复制两个字符串A和B。字符串A的后几个字节和字符串B的前几个字节重叠。
- 习题 8.19(1) 编写一个函数new,对n个字符开辟连续的存储空间,此函数应返回一个指针(地址),指向字符串开始的空间。new(n)表示分配n个字节的内存空间。
- 关于结构指针类型数组做函数参数的一个问题#include<stdio.h>typede
- 一个js对象的代码结构
- C++异常机制的实现方式和开销分析 (大图,编译器会为每个函数增加EHDL结构,组成一个单向链表,非常著名的“内存访问违例”出错对话框就是该机制的一种体现)
- 如果函数的参数是一个指针,不要指望用该指针去申请动态内存。
- 虚函数: 多重继承下派生类对象的内存结构
- 字符串输出输入函数,const修饰符,内存分区,动态内存管理,指针和函数,结构体
- JVM学习笔记(1、 基本结构;2、Java代码编译和执行的整个过程3、内存管理和垃圾回收 4、 内存调优 )
- iOS 面试题(1):一个 Objective-C 对象的内存结构是怎样的?
- 再谈带有虚函数的类对象之内存结构
- JAVA内存使用--如何计算一个Java对象占用的字节数
- drv experiment : 从内核API代码定位函数地址或结构指针地址
- 多态继承情况下,有一个基类指针指向派生类对象,如何用它调用基类的虚函数?
- Delphi函数翻译成VC要注意句柄指针传递(传递Handle的时候,必须加上一个指针引用,才能消除编译错误)
- 建立一个对象数组,内放5个学生数据(学号、成绩),设立一个函数max,用指向对象的指针作函数参数,在max函数中找出5个学生中成绩最高者,并从输出学号。
- 20140228:C++对象内存结构之虚函数
- 实例化一个对象内存分布结构
- 作为一个c++而非c程序员,该弃函数指针投函数对象了