C++ 基類指針和子類指針相互賦值

首先,給出基類animal和子類fish ios

[cpp]   view plain copy
  1. //==============================================================  
  2. //           animal.h  
  3. //  
  4. // begin   : 2012-06-30  
  5. // author  : zwq  
  6. // describe: 非虛函數狀況下,將子類指針賦給積累指針,驗證最終調用  
  7. //           基類函數仍是子類函數。  
  8. //==============================================================  
  9. #ifndef ANIMAL_H  
  10. #define ANIMAL_H  
  11.   
  12. //===============================================================  
  13. //  
  14. //                animal  
  15. //               動物基類  
  16. //  
  17. //===============================================================  
  18. class animal  
  19. {  
  20. public:  
  21.     void breathe();     // 非虛函數  
  22. };  
  23.   
  24. //===============================================================  
  25. //  
  26. //                     animal  
  27. //               魚類,集成於動物基類  
  28. //  
  29. //===============================================================  
  30. class fish : public animal  
  31. {  
  32. public:  
  33.     void breathe();     // 非虛函數  
  34. };  
  35.   
  36. #endif  

 

[cpp]   view plain copy
  1. #include "StdAfx.h"  
  2. #include <iostream>  
  3. #include "Animal.h"  
  4.   
  5. using namespace std;  
  6.   
  7. //===============================================================  
  8. //  
  9. //                animal  
  10. //               動物基類  
  11. //  
  12. //===============================================================  
  13.   
  14. void animal::breathe()  
  15. {  
  16.     cout << "animal breathe" << endl;  
  17. }  
  18.   
  19. //===============================================================  
  20. //  
  21. //                     animal  
  22. //               魚類,集成於動物基類  
  23. //  
  24. //===============================================================  
  25.   
  26. void fish::breathe()  
  27. {  
  28.     cout << "fish bubble" << endl;  
  29. }  



一.基類指針和子類指針之間相互賦值
(1)將子類指針賦值給基類指針時,不須要進行強制類型轉換,C++編譯器將自動進行類型轉換。由於子類對象也是一個基類對象。web

(2)將基類指針賦值給子類指針時,須要進行強制類型轉換,C++編譯器將不自動進行類型轉換。由於基類對象不是一個子類對象。子類對象的自增部分是基類不具備的。
執行如下代碼,看看會報什麼錯誤:app

[cpp]   view plain copy
  1. int main(int argc, char* argv[])  
  2. {  
  3.     ExamAnimal();  
  4.   
  5.     return 0;  
  6. }  
  7.   
  8. void ExamAnimal()  
  9. {  
  10.     // 將子類指針直接賦給基類指針,不須要強制轉換,C++編譯器自動進行類型轉換  
  11.     // 由於fish對象也是一個animal對象  
  12.     animal* pAn;  
  13.     fish* pfh = new fish;  
  14.     pAn = pfh;  
  15.       
  16.     delete pfh;  
  17.     pfh = NULL;  
  18.       
  19.     // 將基類指針直接賦給子類指針,須要強制轉換,C++編譯器不會自動進行類型轉換  
  20.     // 由於animal對象不是一個fish對象  
  21.     fish* fh1;  
  22.     animal* an1 = new animal;  
  23.     // 沒有進行強制類型轉化  
  24.     fh1 = an1;  
  25.   
  26.     delete an1;  
  27.     an1 = NULL;  
  28. }  

編譯時,報以下錯誤信息:函數

--------------------Configuration: CPlusPlusPrimer - Win32 Debug-------------------- Compiling... CPlusPlusPrimer.cpp E:\Study\example\CPlusPlusPrimer\CPlusPlusPrimer.cpp(94) : error C2440: '=' : cannot convert from 'class animal *' to 'class fish *'         Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast Error executing cl.exe.
CPlusPlusPrimer.exe - 1 error(s), 0 warning(s)
根據以上錯題提示信息,對代碼作以下修改:oop

[cpp]   view plain copy
  1. void ExamAnimal()  
  2. {  
  3.     // 將子類指針直接賦給基類指針,不須要強制轉換,C++編譯器自動進行類型轉換  
  4.     // 由於fish對象也是一個animal對象  
  5.     animal* pAn;  
  6.     fish* pfh = new fish;  
  7.     pAn = pfh;  
  8.       
  9.     delete pfh;  
  10.     pfh = NULL;  
  11.       
  12.     // 將基類指針直接賦給子類指針,須要強制轉換,C++編譯器不會自動進行類型轉換  
  13.     // 由於animal對象不是一個fish對象  
  14.     fish* fh1;  
  15.     animal* an1 = new animal;  
  16.     // 修改處:  
  17.     // 進行強制類型轉化  
  18.     fh1 = (fish*)an1;  
  19.   
  20.     delete an1;  
  21.     an1 = NULL;  
  22. }  

 

再次編譯,經過。
二.子類指針賦給基類指針時內存分析 (1)int變量賦給char變量ui

 

整型int轉換爲char類型時,只有一個字節的內容可以放進char類型,剩下的三個字節內容放不下,被截掉,丟失精度。 兩個變量或者對象進行轉換時,必定要看二者的內存模型是否互相匹配。
(2)子類fish指針賦給基類animal指針 下面看看子類fish指針賦給基類animal指針時,內存的變化: 當咱們構造fish類的對象時,首先要調用animal類的構造函數去構造animal類的構造函數,而後才調用fish類的構造函數完成自身部分的構造,從而拼接出一個完整的fish對象。當咱們將fish類對象轉換爲animal類對象時,該對象就被認爲是原對象整個內存模型的上半部分,也就是圖中animal對象的內存部分。當咱們利用類型轉換後的對象指針去調用它的方法時,天然是調用它所在的內存中的方法。 在這裏,animal類對象相似於char類型的對象,fish類對象相似於int類型的對象,將fish類對象賦給animal類對象時,會截取fish類對象自身的部分,剩下fish類對象中的animal部分。
(2)基類animal指針賦給子類fish指針
基類animal對象包含的信息少,類fish對象包含的信息多,將信息少的對象直接轉換爲信息多的對象時(沒有強制類型轉換),顯然是沒法構造出多出的信息。在編譯時,也會發生以下錯誤:error C2440: '=' : cannot convert from 'class animal *' to 'class fish *'。 這時,須要作強制類型轉換:this

[cpp]   view plain copy
  1. // 將基類指針直接賦給子類指針,須要強制轉換,C++編譯器不會自動進行類型轉換  
  2. // 由於animal對象不是一個fish對象  
  3. fish* fh1;  
  4. animal* an1 = new animal;  
  5. // 進行強制類型轉化  
  6. fh1 = (fish*)an1;  
相關文章
相關標籤/搜索