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

深度探索C++对象模型——Data Member的布局(2)书上的错误

2017-09-20 21:22 543 查看
书上给了一个代码实验,比较同一个类中不同access section(访问权限区域)内的两个成员变量的地址,由此来判断哪个section在地址空间中先出现。但书上的这个实验出现了很多错误。以下为书上内容,错误的地方用红色标出。

Data Member的布局

C++ Standard 也允许编译器将多个access sections之中的data members 自由排列,不必在乎它们出现在class声明中的次序,也就是说,下面这样的声明:

class Point3d{
public:
// ...
public:
float x;
static list<Point3d*> * freeList;
public:
float y;
static const int chunkSize = 250;
public:
float z;
};


(上面的x,y,z都是非静态成员变量,是不能用类作用域Point3d::x,Point3d::y,Point3d::z访问的,否则不同对象的x,y,z你知道它访问的是哪一个?)

其class object的大小和组成都和我们先前声明的那个相同,但是members的排列次序则视编译器而定。编译器可以随意把y或z或什么东西放为第一个,不过就我所知,当前没有任何编译器会这么做

当前各家编译器都是把一个以上的access sections(访问区块)连锁在一起,依照声明的次序,成为一个连续区块。Access sections 的多寡并不会招来额外的负担。例如在一个section中声明8个members,或是在8个sections中总共声明8个members,得到的object大小是一样的。

下面这个template function, 接受两个data members,然后判断谁先出现在class object 中,如果两个members都是不同的access sections中的第一个被声明者,此函数就可以用来判断哪一个section先出现:

template<class class_type,
class data_type1,
class data_type2>

char *access_order(
data_type1 class_type::*mem1,
data_type2 class_type::*mem2)
{
assert (mem1 != mem2);
return
mem1 < mem2
? "member 1 occurs first"
: "member 2 occurs first";
}


上述函数可以这样被调用:

access_order(&Poin3d::z,&Point3d::y);


于是class_type会被绑定为Point3d,而data_type1和data_type2会被绑定为float。

以上代码编译会出错

[Error]invalid operands of types 'float Point3d::*' and 'float Point3d::*' to binary 'operator<'


操作符<的左右两边不能是‘float Point3d::*’类型,具体原因目前还不清楚
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息