深度探索C++对象模型———Data Member的绑定

来源:互联网 发布:陈震淘宝店叫什么 编辑:程序博客网 时间:2024/05/20 03:42

3.1 Data Member的绑定(成员变量的绑定)

考虑这样一段代码:

// 某个foo.h头文件,从某处含入extern float x;// 程序员的Point3d.h文件class Point3d {public:    Point3d(float, float, float);    // 问题:被传回和被设定的x是哪一个x?    float X() const { return x; }    void X(float new_x) const { x = new_x; }private:    float x, y, z;};

这段代码中有两个x变量,一个是全局变量:

extern float x;

另一个是类Point3d的成员变量:

Point3d::x;

那么成员函数Point3d::X()中传回的x变量属于global x object还是class内的那个x呢?

  • 对于现代编译器

    几乎所有现代编译器都是把成员函数中的x与成员变量x绑定的(在我们看来也是很自然的)。

  • 对于早期的编译器
    该成员函数Point3d::X()中的x会和全局变量x绑定。这不是我们所期待的!为此,早期的C++出现两种防御性程序设计风格:

1.把所有data members(成员变量)放在class声明起头处,以确保正确的绑定:

class Pointed{    // 防御性程序设计风格 #1    // 在class声明开始先放置所有的data members    float x, y, z;public:    float X() const { return x; }    // ...etc...};

2.把所有的inline functions(成员函数编译器默认为inline),不管大小都放在 class 声明之外:

class Point3d{public:    // 防御性程序设计风格 #2    // 把所有的inlines都移到类之外    Pointed();    float X() const;    void X(float) const;    // ...etc...};inline float POint3d::X() const {    return x;}

这样做的目的:让”成员函数中返回的变量属于global x object还是类内x”在整个class声明之后再分析,如下所示:

extern int x;class Point3d {public:    //对于函数本身的分析将延迟直至    //class声明的右括号出现才开始    float X()const { return x; }private:    float x;};//事实上,分析在这里进行

但是,若上述成员函数带有参数列表(即使是现代编译器),变量还是会立刻分析,如下:

typedef int length;class Point3d{public:    //喔欧:length被决议(resolved)为global    //没问题:_val被决议(resolved)为Point3d::_val    void mumble(length val){_val = val;}    //..private:    //length 必须在“本类对它的第一个参数”之前被看见    //这样的声明将使先前的参数操作不合法    typedef float length;    length _val;    //...};

在这种情况下,(包括现代编译器)任然得使用第一种防御风格的代码,就可以确保非直觉绑定的正确性。

阅读全文
0 0
原创粉丝点击