您的位置:首页 > 编程语言 > C语言/C++

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

2017-09-02 13:40 225 查看

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;
//...
};


在这种情况下,(包括现代编译器)任然得使用第一种防御风格的代码,就可以确保非直觉绑定的正确性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息