C++对象大小和内存结构(一)
C++对象大小和内存结构#
(分为几种情况考虑,再看背后的规则。计算大小的对齐问题占不考虑)
- 空类
- 只含有成员变量的类(静态和非静态)
- 只含有成员函数的类(静态和非静态)
- 只含有虚函数的类
- 有继承的情况(再查资料)
空类##
#include <iostream>
using namespace std;
class NullClass{
//null
};
int main(int argc, char** argv)
{
cout << sizeof(NullClass) << endl;
return 0;
}
输入结果是:1
我查到的解释是,类NullClass是一个空类,但大小并不为零,因为编译器会插入一个隐藏的char,来保证生成不同的对象有不同的地址。如果类中有非静态成员变量或虚函数,则编译器不会自动插入char,因为它们有一定的大小。在下面我们会看到静态成员变量和成员函数(静态和非静态)都不占用对象空间。因为它们分别存储在静态存储区和类对象空间之外(似乎也是在静态存储区)。
只含有成员变量的类##
1. 非静态成员变量###
//为了方便,下面只写类和输出语句
class DataClass{
public:
int m_num;
};
cout << sizeof(DataClass) << endl;
结果是:4
2.静态成员变量###
class StaticDataClass{
public:
static int m_staticNum;
};
cout << sizeof(StaticDataClass) << endl;
结果是:1
类DataClass的大小是4,也就是它的非静态成员变量m_num的大小。而StaticDataClass的大小为1,因为静态成员变量m_staticNum存储在静态存储区,并不占用类对象空间。
只含有成员函数的类##
1. 非静态成员函数###
class FooClass{
public:
void Foo() {cout << "FooClass::Foo" << endl;};
};
cout << sizeof(FooClass) << endl;
结果是:1
2. 静态成员函数###
class StaticFooClass{
public:
static void Foo() {cout << "StaticFooClass::Foo" << endl;};
};
cout << sizeof(StaticFooClass) << endl;
结果是:1
这正印证了之前的说法,非静态成员函数和静态成员函数都在类对象空间之外(暂且相信都在静态存储区),因而它们不占用类对象空间。这样这两个类就跟NullClass类似,编译器自动插入一个char,使其产生不同对象时有不同的地址。
只含有虚函数的类##
class VirtualClass{
public:
virtual void Foo() { cout << "VirtualClass::Foo" << endl;}
}
cout << sizeof(VirtualClass) << endl;
结果是:4
class VirtualClass2{
public:
virtual void Foo() { cout << "VirtualClass::Foo" << endl;}
virtual void Foo2() { cout << "VirtualClass2::Foo2" << endl;}
}
cout << sizeof(VirtualClass2) << endl;
结果是:4
带有虚函数的类,会产生一个虚函数表存放虚函数的地址,无论该类中有多少虚函数都追加到这虚函数表中。虚函数表在类对象的空间之外,为了访问虚函数表,编译器会分类一个指向虚函数表的指针vptr,通过这个指针访问虚函数表。在32位系统下,指针大小就是4byte,因而结果是4。(我看到资料说有的编译器会保留之前提到的char,这样对齐之后得到的大小就是8。)
PS:博客园的markdown不太会用,三级标题下面会自动添加分割线,不知道怎么取消。有知道的请告诉我一下。
浙公网安备 33010602011771号