class X {};
class Y : public virtual X {};
class Z : public virtual X {};
class A : public Y, public Z {};
// sizeof 結果 (視編譯器而異)
sizeof(X); // 1 (空類別插入 1 byte char 確保唯一位址)
sizeof(Y); // 8 (傳統編譯器: vptr 4 + char 1 + padding 3)
sizeof(Z); // 8
sizeof(A); // 12 (vptr 4 + vptr 4 + char 1 + padding 3)
/* 新式編譯器優化:空虛擬基類視為衍生類開頭,Y/Z 大小可能為 4,A 為 8 */
空類別大小非 0:編譯器插入 1 byte 確保物件唯一位址。虛擬繼承引入 vptr 指向虛擬基類子物件,配合對齊 (Alignment) 產生填補位元組。
嵌套型別宣告應置於類別開頭,確保非直覺繫結正確:
typedef int length;
class Point3D {
public:
void mumble(length val) { _val = val; } // length 繫結為 global typedef int
length mumble() { return _val; }
private:
typedef float length; // 此處宣告過晚,導致上方參考非法
length _val;
};
this 指標 + 位移量存取。編譯器轉換:x += pt.x → this->x += pt.x。&Point3D::z 值非單純位移。若類別有虛擬函式,vptr 可能在物件開頭或結尾,位移為 8 或 12。實際值再 +1: