C++对象大小和内存结构(一)

C++对象大小和内存结构#

(分为几种情况考虑,再看背后的规则。计算大小的对齐问题占不考虑)

  1. 空类
  2. 只含有成员变量的类(静态和非静态)
  3. 只含有成员函数的类(静态和非静态)
  4. 只含有虚函数的类
  5. 有继承的情况(再查资料)

空类##

#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不太会用,三级标题下面会自动添加分割线,不知道怎么取消。有知道的请告诉我一下。

posted on 2015-07-27 11:31  DDDNNNN  阅读(255)  评论(0)    收藏  举报

导航