本文講解內容的前提是派生類繼承基類的方式是公有繼承,關鍵字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...