Data 语意学
class X{}; class Y : public virtual X{}; class Z : public virtual X{}; class A : public Y, public Z {};
/* linux 3.10 gcc 4.8.5 X86_64 不一样平台是不一样的*/ sizeof (X) : 1 byte sizeof (Y) : 8 byte sizeof (Z) : 8 byte sizeof (A) : 16 byte
3.1 Data Member 的绑定
1. 对member function本体的分析,会直到整个class的声明都出现了才开始
linux
extern float x; class Point3d { public: Point3d(float, float, float); /* Q : 被传回和被设定的x是哪个x? * A : class内部的x */ float X() const { return x; } void X(float new_x) const { x = new_x; } private: float x, y, z; };
2. 对member function的argument list的分析,是立即完成的。
布局
typedef int length; class Point3d{ public: void mumble(length val){ _val = val; }; // length is "int" not "float" private: typedef float length; length _val; }; /*该这么写*/ typedef int length; class Point3d{ typedef float length; // correct public: void mumble(length val){ _val = val; }; private: length _val; };
3.2 Data Member 的布局
Nonstatic data members在class object中的排列顺序将和其被声明的顺序同样
spa
3.3 Data Member的存取
Point3d origin, *pt = &origin; origin.x = 0.0; pt->x = 0.0;
Q : 从origin存取"和"从pt存取"有什么重大的差别?
当Point3d是一个derived class,而在其继承结构中有一个virtual base class,而且被存取的member是
一个从该virtual base class继承而来的member时,就会有重大的差别".这时不可以说ptr必然指向哪种
class type, 因此这个存取操做必须延迟至执行期经由一个额外的间接导引,才可以解决.
但若是使用origin,就不会有这些问题,其类型无疑是Point3d class
3d
3.4 "继承"与Data Member
class Concrete1 { public: // ... private: int val; char bit1; }; class Concrete2 : public Concrete1 { public: // ... private: char bit2; }; class Concrete3 : public Concrete2 { public: // ... private: char bit3; };
做者扯淡呀, 在gcc上 Concrete3 的大小为8B 没有padding呀!!!!
code