码迷,mamicode.com
首页 > 其他好文 > 详细

Data 语意学 —— 数据成员的绑定、布局与存取

时间:2015-03-04 09:52:52      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:c++   c++对象模型   数据成员存取   

数据成员的绑定

早期的 C++ 编译器为了能够正确绑定具体的数据成员,规定了以下两种行为:

  1. 所有的 data member 必须放在 class 声明的起始处;
  2. 所有的 inline functions 放在 class 声明之外;

从早期的编译器可以知道,绑定数据成员类型必须要在 class 声明完成之后才能确定,但是现在 C++ 编译器不必要要求上面的规定,也可以正确绑定具体的数据成员,例如:

extern float x;

class Pointer{
public:
    Pointer(float, float, float);
    /* 这里返回的 x 是绑定哪个类型的? */

    /* 现在的编译器可以确定绑定的是class 声明内部的 x 值 */
    float X()const {return x;}

    void X(float new_x)const{ x = new_x;}

private:
    float x,y,z;
};

在早期的编译器中 member function 的 argument list 中的名称会在第一次遇到时就会被绑定,例如:

typedef int length;

class Pointer{
public:
    void numble(length val){_val = val;}
    length numble(){return _val};

private:
    typedef float length;
    length _val;
};

从上面的代码可以知道,void numble(length val){_val = val;} length numble(){return _val};中的length被绑定为 int 类型,当 class 出现 nested type(嵌套类型)typedef float length时,C++ standard会把之前的绑定标示为非法;因此,早期的编译器会把 class 出现 nested type(嵌套类型)放在该 class 的起始处;

数据成员的布局

数据成员的布局情况是:

  1. nonstatic data members 在 class object 中的排列顺序和声明顺序一致,任何在其中间声明的 static data member 都不会被放进 object 布局中;
  2. static data member 存放在程序的 data segment 中;

其中 data segement 是程序的虚地址空间的一部分,包含全局变量和静态变量,其大小由程序在运行之前程序员所放置的变量决定。

C++ 标准规定,在同一个access section 即private、public、protected 等区段中,成员的排列只需符合较晚出现的成员在类对象中有较高的地址即可。虚函数表的指针 vptr 放置位置由编译器决定。

数据成员的存取

数据成员的存取根据不同的数据类型有不同的行为,数据类型可能是:static data member、nonstatic data member;数据成员所在的 class 可能是独立的,也可能是派生的(包括:单一继承,多重继承,虚拟继承);

static data members

static data member 位于 class object 之外,且只有一个实例,保存在 data segment 中。不管 static data member 是独立的,或是继承,且不管位于继承(包括虚继承)哪个层次的 class 中,任何对它的操作都将指向内存中的同一地址,这一地址是在编译时确定的;

nonstatic data members

nonstatic data member 直接存放在每一个 class object 之中,对它的存取必须通过 object 的显式 explicit 或隐式 implicit 操作来完成。隐式 implicit 的操作是通过在 member function 使用所属 object 中的 data member 时,对该 data member 的操作实际上是通过 this 指针完成的。对一个 nonstatic data member 进行存取操作,编译器需要把 class object 的起始地址加上 data member 的偏移位置,此偏移位置在编译时确定。

当需要存取的 data member 是从虚拟基类继承而来时,那么通过对象和通过指针存取则差别很大:

  1. 通过对象存取时,即使它继承自虚拟基类,成员的偏移地址也是在编译时期确定的。
  2. 通过指针存取时,由于不知道指针到底指向继承层次中的哪个具体对象,所以对成员变量的存取要在执行时才能确定。

Data 语意学 —— 数据成员的绑定、布局与存取

标签:c++   c++对象模型   数据成员存取   

原文地址:http://blog.csdn.net/chenhanzhun/article/details/44040005

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!