一、简单对象的存储
1、 基本类型对齐原则:
Char 1
Short 2
Int 4
Long 4
Float 4
Double 8
2、 结构体类型对齐原则:
以最大成员类型的对齐方式为准,即当需要增长时,增长最大成员类型所占用的字节数。
3、 静态成员变量不占用类对象的存储空间原则:
静态成员变量所有的类对象共享一份,在静态区域中,并不占用类对象的空间。
4、 没有任何成员变量的类对象占用一个字节的空间
验证程序:vc.net2003下运行结果
#include
using namespace std;
/*没有任何数据成员的对象类占用一个字节的空间*/
class A1
{
};
/*静态数据成员不占用类对象的存储空间*/
class A2
{
char c1;
static int count;
};
/*当只有char类型时,以1个字节为单位对齐*/
class B1
{
char c1;
char c2;
};
/*与A比较发现,当最大为short时,以2个字节为单位对齐*/
class B2
{
char c1;
short s;
};
/*与A比较发现,当最大为int时,以4个字节为单位对齐*/
class B3
{
char c1;
int i;
};
/*与A比较发现,当最大为double时,以8个字节为单位对齐*/
class B4
{
char c1;
float d;
};
/*与A比较发现,当最大为double时,以8个字节为单位对齐*/
class B5
{
char c1;
double d;
};
/*c s i 占4个字节,d占4个字节*/
class C1
{
char c;
short s;
int i;
double d;
};
/*d占4个字节,c s i 占4个字节*/
class C2
{
double d;
char c;
short s;
int i;
};
/*c占1个字节,d从下一个4字节开始占4个字节,s i在下一个4字节中*/
class C3
{
char c;
double d;
short s;
int i;
};
/*c s 在头4个字节中,d占下四个字节,i 在最后4个字节中*/
class C4
{
char c;
short s;
double d;
int i;
};
int main()
{
cout << "size of A1 : " << sizeof(A1) << endl; /*1字节*/
cout << "size of A2 : " << sizeof(A2) << endl; /*1字节*/
cout << endl;
cout << "size of B1 : " << sizeof(B1) << endl; /*2字节*/
cout << "size of B2 : " << sizeof(B2) << endl; /*4字节*/
cout << "size of B3 : " << sizeof(B3) << endl; /*3字节*/
cout << "size of B4 : " << sizeof(B4) << endl; /*8字节*/
cout << "size of B5 : " << sizeof(B5) << endl; /*8字节*/
cout << endl;
cout << "size of C1 : " << sizeof(C1) << endl; /*16字节*/
cout << "size of C2 : " << sizeof(C2) << endl; /*16字节*/
cout << "size of C3 : " << sizeof(C3) << endl; /*24字节*/
cout << "size of C4 : " << sizeof(C4) << endl; /*24字节*/
system("pause");
return 0;
}
二、继承下的对象存储
1、虚表指针占用4个字节原则
对于一个类而言,在不存在虚函数的情况下,类的大小等于成员大小之和(按照对其原则),当存在虚拟函数时,由于要保存虚表指针,故多占用4个字节。
2、子类共享父类的虚表指针原则
在普通继承下,子类与父类共享一个虚表,子类不需要另外添加内存。
3、虚基类表指针占用4字节原则
在虚继承的情况下,继承了多个继承了同一个父类的中间类的子类只保存了一个同他基类的备份,但每个中间类都需要需要保存指向基类表的指针来指向共同的基类。
#include
using namespace std;
class A1
{
int numA1;
};
/*与A1比较,存在虚函数的情况下,需要保存虚函数表指针占4个字节*/
class A2
{
int numA2;
virtual FunA2();
};
/*与A2比较,当不存在不同于父类的虚函数时,子类与父类共享保存虚函数表的指针*/
class B1 : A2
{
int numB1;
};
/*与A2比较,当存在不同于父类的虚函数时,子类与父类共享保存虚函数表的指针*/
class B2 : A2
{
int numB2;
virtual FunB2();
};
/*与B1比较,虚继承需要保存指向虚基类表的指针占4个字节*/
class B3 : virtual A2
{
int numB3;
};
/*虚继承下,若子类中有不同于父类的虚函数,则需要不同于父类的指向虚函数表的指针*/
class B4 : virtual A2
{
int numB4;
virtual FunB4();
};
/*虚继承下,共同的基类只有一个备份,但每个虚继承的类中多了一个只想那个虚基类表的指针*/
class C1 : B3, B4
{
int numC1;
};
void main()
{
cout << "sizeof A1 is : " << sizeof(A1) << endl; /* 4 */
cout << "sizeof A2 is : " << sizeof(A2) << endl; /* 8 */
cout << endl;
cout << "sizeof B1 is : " << sizeof(B1) << endl; /* 12 */
cout << "sizeof B2 is : " << sizeof(B2) << endl; /* 12 */
cout << "sizeof B3 is : " << sizeof(B3) << endl; /* 16 */
cout << "sizeof B4 is : " << sizeof(B4) << endl; /* 20 */
cout << endl;
cout << "sizeof C1 is : " << sizeof(C1) << endl; /* 32 */
system("pause");
}
C的内存分布:
B3指向虚基类表的指针 4
B3自己的存储区域 4
B4自己的指向虚函数表的指针 4
B4指向虚基类表的指针 4
B4自己的存储区域 4
C1自己的存储区域 4
基类的存储区域 8
文章分类:C++编程
思考题:
我们可以说,静态数据成员和静态成员函数时类的一部分,而不是对象的一部分(谭老师说的)。
那么,对于非静态成员函数来说,又是怎样的呢?
回答:
我们先来成员函数的存储方式。
我们都知道,一个类包含数据和函数。当我们实例化一个对象的时候,因为这个对象是用类定义的,那么它理所当然拥有了这个类的数据和函数。但是,一般情况下,不同的对象,他们的的数据值不同,但是函数的代码都相同。所以,为了节约存储空间(想象一下我们如果定义了100个对象,那么用100段内存空间存储相同的代码,岂不是很浪费?),我们让成员函数的代码共享。
我们把成员函数的代码存储在对象空间之外。换句话说,成员函数的代码,都不占据对象的存储空间。它会被存在其他地方。
所以类的成员函数,对于类来讲。一方面是逻辑上的“属于”,一方面是物理上的“不依赖“。
回到思考题上来,对于非静态成员函数来说,它当然是对象的一部分。(只是因为存储方式上的特殊性,容易让人误解!)
实例:
我们来举一个例子,说明,成员函数的代码没有存放在C++编译器为对象申请的内存空间中。
-
-
-
-
-
- #include "stdafx.h"
- #include
- using namespace std;
- class Time
- {
- private:
- int hour;
- int minute;
- int sec;
- void setTime(int a, int b, int c)
- {
- hour = a;
- minute = b;
- sec = c;
- }
- };
- int _tmain(int argc, _TCHAR* argv[])
- {
- cout << "The Byte Number of 'Time' is :" << endl;
- cout << sizeof(Time) <
- return 0;
- }
//////////////////////////////////////////////////////////////////////////
// author : Erin
// date : 20100721
// introduction : reveal the storing way of MemberFunction of a Class
//////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include
using namespace std;
class Time
{
private:
int hour;
int minute;
int sec;
void setTime(int a, int b, int c)
{
hour = a;
minute = b;
sec = c;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
cout << "The Byte Number of 'Time' is :" << endl;
cout << sizeof(Time) < sizeof 方法用于求类的字节数。由此可知Time类对象(如果实例化的话)的字节数为12。已知int类对象的字节数为4,即有sizeof(int)=4。故知一个对象所占的内存空间大小只取决于该对象中数据成员所占空间,而与成员函数无关。
http://erintojerry.javaeye.com/blog/718185
阅读(1977) | 评论(1) | 转发(0) |