C 基類和派生類之間的轉換

2022-09-12 00:51:35 字數 2955 閱讀 8344

本文講解內容的前提是派生類繼承基類的方式是公有繼承,關鍵字public

以下程式為講解用例。

1 #include2 using namespace std;

3 4 class a

5 8 void display();

9 private:

10 int m;

11 int n;

12 };

13 14 void a::display()

15 19

20 class b :public a

21 24 void display();

25 private:

26 int p;

27 };

28 29 void b::display()

30 34

35 void print1(a& a)

36 39

40 void print2(b& b)

41 44

45 void print3(a a)

46 49

50 void print4(b b)

51 54

55 int main()

56

切記:派生類物件是基類物件,派生類中包含有基類的成員。基類物件不是派生類物件,它不能包含派生型別的成員。

/**************派生類到基類的轉化**************/

1。派生類物件位址賦值給基類指標

main函式中執行以下**

1     a a(3, 4);

2 // a.display();

3 b b(10, 20, 30);

4 // b.display();

5 6 a * pa;

7 // b * pb;

8 // pa = &a;

9 // pa->display();

10 // pb = &b;

11 // pb->display();

12 13 pa = &b;

14 pa->display(); //會輸出 10 20

pa為基類指標,指向派生類物件是合法的,因為派生類物件也是基類物件。語句會輸出派生類物件中基類部分。

注意:這裡並不會呼叫派生類的display函式,呼叫的是基類的display函式,因為指標pa是基類指標,編譯器在編譯階段只知道pa的型別。如果要實現呼叫派生類的display函式,

需要用到虛函式實現多型性。之後的文章會講到。

進一步解釋一下編譯時和執行時的區別。

編譯時編譯器能知道pa的型別為a *,但是不知道它指向了哪個物件,假如有以下語句

1 a a(3, 4);

2 b b(10, 20, 30);

3 a* pa;

4 int number;

5 cin >> number;

6 if (number >= 0)

7 pa = &a;

8 else

9 pa = &b;

pa指向的物件型別依賴於輸入,執行時才輸入,所以編譯器是沒有辦法知道pa指向哪個型別的。

2.派生類物件賦值給基類引用

/**引用跟指標基本沒有區別,引用本質上是指標,是個指標常量,具體可以參照我的另一篇c++中的引用和指標的聯絡和區別**/

main函式中執行以下**

1 a a(3, 4);

2 b b(10, 20, 30);

3 print1(b); //會輸出 10 20

形參為基類引用,實參為派生類物件,派生類物件也是基類物件,可以賦值給基類引用。輸出派生類中基類部分。

注意:此時物件本身並未複製,b仍然是派生類物件,前面說過了引用就是乙個指標。

3.派生類物件賦值給基類物件。

a a(3, 4);

b b(10, 20, 30);

print3(b);

派生類物件基類部分被複製給形參。

注意:實際上沒有從派生類物件到基類物件的直接轉換。對基類物件的賦值或初始化,實際上在呼叫函式,初始化時呼叫建構函式,賦值時呼叫賦值操作符。

/********************基類到派生類的轉化******************/

切記:這種轉換有可能引發嚴重的安全問題,編寫**時不要使用。沒有基類到派生類的自動轉換,原因在於基類物件只能是基類物件,不能包含派生型別的成員。

如果允許用基類物件給派生類物件賦值,那麼就可以試圖使用該派生類物件訪問不存在的成員。

1 a a(3, 4);

2 b b(10, 20, 30);

3 a * pa;

4 b * pb;

5 // print2(a); //錯誤。不能用基類物件給派生類引用賦值。

6 // print4(a); //錯誤。不能用基類物件給派生類物件賦值。

7 // pb = &a; //錯誤。派生類指標不能指向基類物件。

8 9 pa = &a;

10 pb = &b;

11 12 //pb = pa; //錯誤。不能用基類指標給派生類指標賦值。

13 14 pb = (b*)pa; //可以強制轉換,但是非常不安全。

15 pb->display(); //出現安全問題,p無法訪問,因為a中沒有p成員

注意到我們使用強制轉換時,當派生類新增了基類中不存在的成員時,會出現安全問題。

pb->display();會呼叫派生類的display函式,但是它指向的記憶體是基類物件a的記憶體,p不存在。會出現嚴重後果。

派生類到基類的轉換 和基類到派生類的轉換

一 基類與派生類的轉換 3種繼承方式 公用 保護 私有繼承 中,公用派生類才是基類真正的子型別,它完整地繼承了基類的功能。不同型別資料之間在一定條件下可以進行型別的轉換。基類與派生類物件之間是否也有賦值相容的關係,可否進行型別間的轉換?回答是可以的。基類與派生類物件之間有賦值相容關係,由於派生類中包...

C 基類指標和派生類指標之間的轉換

函式過載只會發生在同作用域中 或同乙個類中 函式名稱相同,但引數型別或引數個數不同。函式過載不能通過函式的返回型別來區分,因為在函式返回之前我們並不知道函式的返回型別。函式隱藏和函式覆蓋只會發生在基類和派生類之間。函式隱藏是指派生類中函式與基類中的函式同名,但是這個函式在基類中並沒有被定義為虛函式,...

派生類和基類之間的關係

1 派生類物件可以使用基類的方法,條件是方法不是私有的 ratedplayer rplayer 1140,mallory duck true rplayer.name 2 基類指標可以在不進行顯示型別轉換的情況下指向派生類物件 3 基類引用可以在不進行顯式型別轉換的情況下引用派生類物件 ratedp...