子類與父類之間的類型轉換
先給一段代碼
class Base {
public:
int a = 10;
};
class pub_Derv : public Base {
Base *getBase() {return this;}
};
class prot_Derv : protected Base {
Base *getBase() {return this;}
};
class priv_Derv : private Base {
Base *getBase() {return this;}
};
class pub_pub_Derv : public pub_Derv {
Base *getBase() {return this;}
};
class pub_prot_Derv : public prot_Derv {
Base *getBase() {return this;}
};
class pub_priv_Derv : public priv_Derv {
//Base *getBase() {return this;}
};
1、對象類型不存在類型轉換
Base b;
pub_Derv pd;
b = pd; // 是調用了Base的拷貝構造函數,而不是類型轉換
pd = b; // 調用pub_Derv的拷貝賦值運算符,但是Base類型不能轉為pub_Derv類型的引用,這個語句會報錯。
2、子類的指針或引用轉為父類的指針或引用:子類--->父類
不是子類的指針或引用就能轉為父類的指針或引用,前提條件是子類的指針或引用在當前域(域內:類體類->成員函數和友元函數 域外:類體外)能夠訪問訪問父類的public的成員,因為父類對象在域外就是能訪問其public成員。
- 子類對象在域外
Base *p;
p = new pub_Derv; // 正確轉換,Base的public成員在pub_Derv中還是public的,所以pub_Derv的域外對象能夠訪問Base的public成員。
p = new prot_Derv; // 錯誤轉換,Base的public成員在prot_Derv中還是protected的,所以prot_Derv的域外對象不能訪問Base的public成員。
p = new priv_Derv; // 錯誤轉換,Base的public成員在priv_Derv中還是private的,所以priv_Derv的域外對象不能訪問Base的public成員。
p = new pub_pub_Derv; // 正確轉換,Base的public成員在pub_pub_Derv中還是public的,所以pub_pub_Derv的域外對象能夠訪問Base的public成員。
p = new pub_prot_Derv; // 錯誤轉換,Base的public成員在pub_prot_Derv中是protected的,所以pub_prot_Derv的域外對象不能訪問Base的public成員。
p = new pub_priv_Derv; // 錯誤轉換,Base的public成員在pub_priv_Derv中是inaccessible的,所以pub_priv_Derv的域外對象不能訪問Base的public成員。
- 子類對象在域內
class pub_prot_Derv : public prot_Derv {
// 正確轉換,Base的public成員在pub_prot_Derv中是protected的,pub_prot_Derv的域內對象能夠訪問pub_prot_Derv的protected成員,
// 所以pub_prot_Derv的域內對象能轉換為Base對象。
Base *getBase() {return this;}
};
class pub_priv_Derv : public priv_Derv {
// 錯誤轉換,因為Base的public成員在priv_Derv中是private的,到了pub_priv_Derv就變成inaccessible的了,也就是說在pub_priv_Derv的域內
// 也訪問不了Base的public成員,所以pub_priv_Derv的域內對象不能轉換為Base對象。
Base *getBase() {return this;}
};
3、父類指針或引用轉為子類指針或引用:父類--->子類
Base *pb = new pub_Derv;
// 父類指針或引用本來就是指向子類對象,則可以通過強制類型轉換進行父類到子類的轉換,來屏蔽編譯器的檢測,
// 如果父類不是指向之類,而這樣轉換就很危險了。
pub_Derv pb2 = static_case<pub_Derv>(pb);