1)C++对象大小计算
2014-12-10 22:49
211 查看
C++对象的大小不同的编译器的实现是不一样的,以下仅讨论.net2003,其他编译的可能出现的结果以下也做了分析和猜测。在反推不同编译器实现的C++对象的大小时。对齐是一个很重要也容易被遗忘的问题。
class A{};
类A是一个空类,但是它的大小并不为0,编译期间编译器会插入一个char在其中,这个char我们是看不到的,这样的用处是保证生成的不同对象具有不同地址,就是要对象里有东西。
class B:public virtual A{};
B类是对A类的虚继承,B中一般会有指向A的实例的指针,在IA-32下为4bytes。这里不同编译器的实现差别很大,有的编译器在B的对象中也 会保留A类的那个隐含的char,于是就有1+4=5个bytes,再考虑对齐,有些编译器产生的结果为8bytes,但是在.net2003中优化过了,不会有A中的char,也就不需要对齐,只有4bytes大
class C:public virtual A{};//同上
class D:public B,public C{};
//D为8,如果编译器不优化A中的char就会有1(A)+8(B)+8(C)-4(B对A虚继承)-4(C对A虚继承)+3(对齐)=12bytes
class E{
int i;
};//很明显4bytes
class F{
double d;
};//很明显8bytes
class G{
double num;
char in;
};//8bytes对齐,所以是8(double)+4(int)+4(对齐)=16
class H{
int num;
double in;
};//同上
class I{
int num;
double in;
public:
virtual ~I(){};
};//8(double)+4(int)+4(对齐)+4(vptr)+4(对齐)=24
class J{
double num;
int in;
public:
virtual ~J(){};
};//同上8(double)+4(int)+4(对齐)+4(vptr)+4(对齐)=24
class K{
int i;
int k;
public:
virtual ~K(){};
};//4(int)+4(int)+4(vptr)=12
class L{
int i;
int j;
L(){};
public:
float ll(int i) {
return 0.0;
}
static int hhh(int i) {
return 0.0;
}
virtual ~L(){};
virtual ji(){};
};
//虚函数表的指针vptr,只有类中出现虚函数才会出现,它指向虚函数表,所有虚函数的地址存放在此表中。
//4(int)+4(int)+4(vptr)=12从中看出,不管有多少虚函数,大小不变,因为类中之保存虚函数表。
//不管成员函数有多少,类大小也不变,因为他们不保存在对象中,无论是否是静态
int main(){
cout <<"A "<<sizeof(A)<<endl;
cout <<"B "<<sizeof(B)<<endl;
cout <<"C "<<sizeof(C)<<endl;
cout <<"D "<<sizeof(D)<<endl;
cout <<"E "<<sizeof(E)<<endl;
cout <<"F "<<sizeof(F)<<endl;
cout <<"G "<<sizeof(G)<<endl;
cout <<"H "<<sizeof(H)<<endl;
cout <<"I "<<sizeof(I)<<endl;
cout <<"J "<<sizeof(J)<<endl;
cout <<"K "<<sizeof(K)<<endl;
cout <<"L "<<sizeof(L)<<endl;
}
/*******************************************************************/
output .net2003
A 1
B 4
C 4
D 8
E 4
F 8
G 16
H 16
I 24
J 24
K 12
L 12
class A{};
类A是一个空类,但是它的大小并不为0,编译期间编译器会插入一个char在其中,这个char我们是看不到的,这样的用处是保证生成的不同对象具有不同地址,就是要对象里有东西。
class B:public virtual A{};
B类是对A类的虚继承,B中一般会有指向A的实例的指针,在IA-32下为4bytes。这里不同编译器的实现差别很大,有的编译器在B的对象中也 会保留A类的那个隐含的char,于是就有1+4=5个bytes,再考虑对齐,有些编译器产生的结果为8bytes,但是在.net2003中优化过了,不会有A中的char,也就不需要对齐,只有4bytes大
class C:public virtual A{};//同上
class D:public B,public C{};
//D为8,如果编译器不优化A中的char就会有1(A)+8(B)+8(C)-4(B对A虚继承)-4(C对A虚继承)+3(对齐)=12bytes
class E{
int i;
};//很明显4bytes
class F{
double d;
};//很明显8bytes
class G{
double num;
char in;
};//8bytes对齐,所以是8(double)+4(int)+4(对齐)=16
class H{
int num;
double in;
};//同上
class I{
int num;
double in;
public:
virtual ~I(){};
};//8(double)+4(int)+4(对齐)+4(vptr)+4(对齐)=24
class J{
double num;
int in;
public:
virtual ~J(){};
};//同上8(double)+4(int)+4(对齐)+4(vptr)+4(对齐)=24
class K{
int i;
int k;
public:
virtual ~K(){};
};//4(int)+4(int)+4(vptr)=12
class L{
int i;
int j;
L(){};
public:
float ll(int i) {
return 0.0;
}
static int hhh(int i) {
return 0.0;
}
virtual ~L(){};
virtual ji(){};
};
//虚函数表的指针vptr,只有类中出现虚函数才会出现,它指向虚函数表,所有虚函数的地址存放在此表中。
//4(int)+4(int)+4(vptr)=12从中看出,不管有多少虚函数,大小不变,因为类中之保存虚函数表。
//不管成员函数有多少,类大小也不变,因为他们不保存在对象中,无论是否是静态
int main(){
cout <<"A "<<sizeof(A)<<endl;
cout <<"B "<<sizeof(B)<<endl;
cout <<"C "<<sizeof(C)<<endl;
cout <<"D "<<sizeof(D)<<endl;
cout <<"E "<<sizeof(E)<<endl;
cout <<"F "<<sizeof(F)<<endl;
cout <<"G "<<sizeof(G)<<endl;
cout <<"H "<<sizeof(H)<<endl;
cout <<"I "<<sizeof(I)<<endl;
cout <<"J "<<sizeof(J)<<endl;
cout <<"K "<<sizeof(K)<<endl;
cout <<"L "<<sizeof(L)<<endl;
}
/*******************************************************************/
output .net2003
A 1
B 4
C 4
D 8
E 4
F 8
G 16
H 16
I 24
J 24
K 12
L 12
相关文章推荐
- C++回顾之static成员、static成员函数及类对象大小计算
- 三十二、C++内存布局,对象大小计算、虚函数虚继承对类内存模型的影响
- C++ 类对象大小计算(一)常规情况
- C++ 类对象大小计算(二)含有虚函数类
- C++回顾之static成员、static成员函数及类对象大小计算
- C++中对象大小的问题
- c++中利用sizeof运算符计算结构体大小问题探讨
- 算法 - 有两个相同大小数组均已按升序排列好,编程计算这两个数组的中位数(C++)
- 关于类对象大小的 sizeof 计算问题
- Java程序计算各种对象所占内存的大小的方法
- AS3 求Matrix变形后计算显示对象大小的矩形框算法
- 关于类对象大小的 sizeof 计算问题(续)
- JAVA对象所占字节大小计算方法
- 思路:C++数组大小的计算可以根据所占空间的大小。
- 关于类对象大小的 sizeof 计算问题
- 关于类对象大小的 sizeof 计算问题
- C++ sizeof 计算类的大小
- c++对象大小
- C++中虚函数工作原理和(虚)继承类的内存占用大小计算
- java对象占用内存大小计算方法