先給一段代碼
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);