Chinaunix首页 | 论坛 | 博客
  • 博客访问: 770958
  • 博文数量: 95
  • 博客积分: 6011
  • 博客等级: 准将
  • 技术积分: 1342
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-12 16:58
文章分类

全部博文(95)

文章存档

2009年(44)

2008年(51)

我的朋友

分类: C/C++

2008-09-03 19:34:18

 
(一) 独立类且无虚函数
先从普通的类对象的布局说起:
(从无成员的空类->有数据和函数成员的类->含有静态成员的类)

1. C000为一个空类。

 

1)定义和实验如下:
struct C000
{
};
运行如下代码打印它的大小及对象中的内容。
PRINT_SIZE_DETAIL(C000)
结果为:
The size of C000 is 1
The detail of C000 is cc

2)对象布局(对象布局中按:(变量名称,初值,变量内存大小)的形式标示)
C000:
   



3)相关说明
注意一个没有任何成员函数的类是一个1个字节的对象。可以看到它的大小为1字节,这是一个占位符。我们可以看到它的值是0xcc。在debug模式下,这表示是由编译器插入的调试代码所初始化的内存。在release模式下可能是个随机值,我测试时值为0x00。
 
2. 定义两个类,含有普通成员函数。C010和C011如下:
 

1)定义和实验:
struct C010
{
C010() : c_(0x01) {}
void foo() { c_ = 0x02; }
char c_;
};
struct C011
{
C011() : c1_(0x02), c2_(0x03) {}
char c1_;
char c2_;
};
运行如下代码打印它们的大小及对象中的内容。
PRINT_SIZE_DETAIL(C010)
PRINT_SIZE_DETAIL(C012)
结果为:
The size of C010 is 1
The detail of C010 is 01
The size of C011 is 2
The detail of C011 is 02 03

2)  对象布局
C010:
    

C011:

    

3)相关说明
我们从对象的内存输出中可以看到,它们的值就是我们在构造函数中赋的值,C010为0x01,C011为0x0203。大小分别为1、2。普通成员函数在对象布局中不占空间。

3. 定义C012类,含有静态成员函数和静态数据。

1)定义和实验:
struct C012
{
static int sfoo() { return 1; }
int foo() { return 1; }
char c_;
static int i_;
};
int C012::i_ = 1;
在这个类中我们加入了一个静态数据成员,一个普通成员函数和一个静态成员函数。
运行如下代码打印它的大小及对象中的内容。
PRINT_SIZE_DETAIL(C012)
结果为:
The size of C012 is 1
The detail of C012 is cc

2)对象布局:
C012:

4)相关说明:
可以看到它的大小还是1字节,值为0xcc是因为我们没有初始化它,原因前面说过了。在图示中,省写了。

 
总述: 

  刚才讲了类的成员有:数据成员(静态和非静态数据成员)和函数成员(静态、非静态、虚函数)。需要多少内存需要多少的内存才能够表现一个class object?1)其nonstatic data members的总和大小;2)加上任何由于alignment的需求而填补上去的空间,可能存在于members之间,也可能存在于集合体边界(在我们的例子中不予考虑);3)加上为了支持virtual而由内部产生的任何额外负担。另外,在各个访问区段,在同一个访问区段内(如public),数据是按声明的顺序来排列的,但是各个访问区段之间的要求是不被要求的,即区段之间的排列是自由的。这是对于任何类都支持的,对于独立的类来说,其内存布局是:1)其nonstatic data members的总和大小;2)加上任何由于alignment的需求而填补上去的空间,可能存在于members之间,也可能存在于集合体边界;从上面的结果我们可以映证,普通成员函数,静态成员函数,及静态成员变量皆不会在类的对象中有所表示,成员函数和对象的关联由编译器在编译时处理,正如我们会在后面看到的那样,编译器会在编译时决议出正确的普通成员函数地址,并将对象的地址以this指针的方式,做为第一个参数传递给普通成员函数,以此 来进行关联。静态成员函数类似于全局函数,不和具体的对象关联。静态成员变量也一样。静态成员函数和静态成员变量和普通的全局函数及全局变量不同之处在于它们多了一层名字限定。



阅读(850) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~