C++中基類和派生類之間的轉換實例教程
本文實例講解了C++中基類和派生類之間的轉換。對于深入理解C++面向對象程序設計有一定的幫助作用。此處需要注意:本文實例講解內容的前提是派生類繼承基類的方式是公有繼承,關鍵字public。具體分析如下:
以下程序為講解示例:
#include<iostream>
using namespace std;
class A
{
public:
A(int m1, int n1):m(m1), n(n1){}
void display();
private:
int m;
int n;
};
void A::display()
{
cout << "m = " << m << endl;
cout << "n = " << n << endl;
}
class B :public A
{
public:
B(int m1, int n1, int p1) :A(m1, n1), p(p1){}
void display();
private:
int p;
};
void B::display()
{
A::display();
cout << "p = " << p << endl;
}
void print1(A& a)
{
a.display();
}
void print2(B& b)
{
b.display();
}
void print3(A a)
{
a.display();
}
void print4(B b)
{
b.display();
}
int main()
{
A a(3, 4);
// a.display();
B b(10, 20, 30);
// b.display();
A * pa;
B * pb;
pa = &a;
// pa->display();
pb = &b;
// pb->display();
// pa = &b;
// pa->display();
// pb = &a; //錯誤。派生類指針不能指向基類對象。
// print1(b);
// print2(a); //錯誤。不能用基類對象給派生類引用賦值。
// print3(b);
// print4(a); //錯誤。不能用基類對象給派生類對象賦值。
// pb = pa; //不能用基類指針給派生類指針賦值。
pb = (B*)pa; //可以強制轉換,但是非常不安全。
pb->display(); //出現安全問題,p無法訪問,因為a中沒有p成員
system("pause");
return 0;
}
切記:派生類對象是基類對象,派生類中包含有基類的成員?;悓ο蟛皇桥缮悓ο?,它不能包含派生類型的成員。
一、派生類到基類的轉化
1.派生類對象地址賦值給基類指針
main函數中執(zhí)行以下代碼
A a(3, 4); // a.display(); B b(10, 20, 30); // b.display(); A * pa; // B * pb; // pa = &a; // pa->display(); // pb = &b; // pb->display(); pa = &b; pa->display(); //會輸出 10 20
pa為基類指針,指向派生類對象是合法的,因為派生類對象也是基類對象。語句會輸出派生類對象中基類部分。
注意:這里并不會調用派生類的display函數,調用的是基類的display函數,因為指針pa是基類指針,編譯器在編譯階段只知道pa的類型。如果要實現調用派生類的display函數,需要用到虛函數實現多態(tài)性。之后的文章會講到。
進一步解釋一下編譯時和運行時的區(qū)別。
編譯時編譯器能知道pa的類型為A *,但是不知道它指向了哪個對象,假如有以下語句
A a(3, 4); B b(10, 20, 30); A* pa; int number; cin >> number; if (number >= 0) pa = &a; else pa = &b;
pa指向的對象類型依賴于輸入,運行時才輸入,所以編譯器是沒有辦法知道pa指向哪個類型的。
2.派生類對象賦值給基類引用
引用跟指針基本沒有區(qū)別,引用本質上是指針,是個指針常量,具體可以參照我的另一篇C++中的引用和指針的聯(lián)系和區(qū)別
main函數中執(zhí)行以下代碼
A a(3, 4); B b(10, 20, 30); print1(b); //會輸出 10 20
形參為基類引用,實參為派生類對象,派生類對象也是基類對象,可以賦值給基類引用。輸出派生類中基類部分。
注意:此時對象本身并未復制,b仍然是派生類對象,前面說過了引用就是一個指針。
3.派生類對象賦值給基類對象。
A a(3, 4); B b(10, 20, 30); print3(b);
派生類對象基類部分被復制給形參。
注意:實際上沒有從派生類對象到基類對象的直接轉換。對基類對象的賦值或初始化,實際上在調用函數,初始化時調用構造函數,賦值時調用賦值操作符。
二、基類到派生類的轉化
切記:這種轉換有可能引發(fā)嚴重的安全問題,編寫代碼時不要使用。沒有基類到派生類的自動轉換,原因在于基類對象只能是基類對象,不能包含派生類型的成員。
如果允許用基類對象給派生類對象賦值,那么就可以試圖使用該派生類對象訪問不存在的成員。
A a(3, 4); B b(10, 20, 30); A * pa; B * pb; // print2(a); //錯誤。不能用基類對象給派生類引用賦值。 // print4(a); //錯誤。不能用基類對象給派生類對象賦值。 // pb = &a; //錯誤。派生類指針不能指向基類對象。 pa = &a; pb = &b; //pb = pa; //錯誤。不能用基類指針給派生類指針賦值。 pb = (B*)pa; //可以強制轉換,但是非常不安全。 pb->display(); //出現安全問題,p無法訪問,因為a中沒有p成員
注意到我們使用強制轉換時,當派生類添加了基類中不存在的成員時,會出現安全問題。
pb->display();會調用派生類的display函數,但是它指向的內存是基類對象a的內存,p不存在。會出現嚴重后果。
欄 目:C語言
下一篇:16種C語言編譯警告(Warning)類型的解決方法
本文標題:C++中基類和派生類之間的轉換實例教程
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/3456.html
您可能感興趣的文章
- 04-02c語言沒有round函數 round c語言
- 01-10深入理解C++中常見的關鍵字含義
- 01-10使用C++實現全排列算法的方法詳解
- 01-10c++中inline的用法分析
- 01-10用C++實現DBSCAN聚類算法
- 01-10全排列算法的非遞歸實現與遞歸實現的方法(C++)
- 01-10C++大數模板(推薦)
- 01-10淺談C/C++中的static與extern關鍵字的使用詳解
- 01-10深入C/C++浮點數在內存中的存儲方式詳解
- 01-10深入理解C/C++混合編程


閱讀排行
本欄相關
- 04-02c語言函數調用后清空內存 c語言調用
- 04-02func函數+在C語言 func函數在c語言中
- 04-02c語言的正則匹配函數 c語言正則表達
- 04-02c語言用函數寫分段 用c語言表示分段
- 04-02c語言中對數函數的表達式 c語言中對
- 04-02c語言編寫函數冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數 round c語言
- 04-02c語言分段函數怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數 c語言中怎
- 04-02c語言調用函數求fibo C語言調用函數求
隨機閱讀
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-10C#中split用法實例總結
- 01-11ajax實現頁面的局部加載
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 08-05dedecms(織夢)副欄目數量限制代碼修改
- 04-02jquery與jsp,用jquery
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文


