书113页,最终的代码如下:
#include<iostream>
//译注:以下的 Point2d 声明请与第101页的声明进行比较
class Point2d {
public:
Point2d( float x= 0.0, float y = 0.0):_x(x),_y(y){ };
//×和y的存取函数与前一版相同。
//由于对不同维度的点,这些函数操作固定不变,所以不必设计为 virtual
//加上z的保留空间(目前什么也没做)
virtual float z()const { return 0.0;}//译注:2d点的z为0.0是合理的
virtual void z( float ){ }
// 设定以下的运算符为 virtual
virtual void operator+=(const Point2d& rhs ) {
_x += rhs.x();
_y += rhs.y();
}
// ... more members
float x()const{
return _x;
}
float y()const{
return _y;
}
protected:
float _x,_y;
};
class Point3d:public Point2d {
public:
Point3d(float x=0.0,float y=0.0,float z=0.0):Point2d(x,y),_z(z){ };
float z(){
fprintf(stderr,"here\n");
return _z;
}
void z(float newZ){_z=newZ;}
void operator+=(const Point2d& rhs){
Point2d::operator+=(rhs);
_z+=rhs.z();
}
protected:
float _z;
};
class Vertex{
public:
~Vertex(){}
protected:
Vertex* next;
};
class Vertex3d:public Point3d,public Vertex{
public:
protected:
float mumble;
};
对象模型如下:
class Vertex3d size(24):
+---
0 | +--- (base class Point3d)
0 | | +--- (base class Point2d)
0 | | | {vfptr}
4 | | | _x
8 | | | _y
| | +---
12 | | _z
| +---
16 | +--- (base class Vertex)
16 | | next
| +---
20 | mumble
+---
Vertex3d::$vftable@:
| &Vertex3d_meta
| 0
0 | &Point3d::z
1 | &Point2d::z
2 | &Point3d::+=
Microsoft (R) Incremental Linker Version 14.29.30151.0
对比书115页,可以看到现代编译器的生成的对象模型和以前模型的差异.
正如作者在前几页说的几个改变,现代编译器会将vftptr放置在对象顶部,而且最终只会有一个vftprt