深度探索C++對象模型 chapter 3

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

clipboard.png

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 class3d

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

相關文章
相關標籤/搜索