日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

派生类到基类的转换 和基类到派生类的转换

發布時間:2025/6/15 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 派生类到基类的转换 和基类到派生类的转换 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、 基類與派生類的轉換

????3種繼承方式(公用、保護、私有繼承)中,公用派生類才是基類真正的子類型,它完整地繼承了基類的功能。

????不同類型數據之間在一定條件下可以進行類型的轉換。基類與派生類對象之間是否也有賦值兼容的關系,可否進行類型間的轉換?回答是可以的。基類與派生類對象之間有賦值兼容關系,由于派生類中包含從基類繼承的成員,因此可以將派生類的值賦給基類對象,在用到基類對象的時候可以用其子類對象代替?

注意:有的數據類型是不可轉換的;有的轉換是不可逆的。

1、派生類對象可以向基類對象賦值。

可以用子類(即公用派生類)對象對其基類對象賦值。

如:?
??? A al;?//定義基類A對象al?

??? B bl;?
//定義類A的公用派生類B的對象bl?
??? a1=b1;?
//用派生類B對象bl對基類對象al賦值

實際上,所謂賦值只是對數據成員賦值,對成員函數不存在賦值問題。

注意:
????
1、賦值后不能企圖通過對象a1去訪問派生類對象bl的成員,因為bl的成員與al的成員是不同的。假設ase是派生類B中增加的公用數據成員,分析下面的用法:

a1.age=23;//錯誤,al中不包含派生類中增加的成員?
b1.age=21;//正確,b1中包含派生類中增加的成員

????2、子類型關系是單向的、不可逆的。B是A的子類型,不能說A是B的子類型。只能用子類對象對其基類對象賦值,而不能用基類對象對其子類對象賦值,理由是顯然的,因為基類對象不包含派生類的成員,無法對派生類的成員賦值。同理,同一基類的不同派生類對象之間也不能賦值。

2、派生類對象可以替代基類對象向基類對象的引用進行賦值或初始化?

如已定義了基類A對象a1,可以定義a1的引用:

A al;?//定義基類A對象al?
B bl;?//定義公用派生類B對象bl?
A&r=al;//定義基類A對象的引用變量r,并用a1對其初始化

????引用r是al的別名,r和a1共享同一段存儲單元。可以用子類對象初始化引用r,將上面最后一行改為:

????A&r=bl;//定義基類A對象的引用變量r,并用派生類B對象b1對其初始化或者保留上面第3行“A&r=al;”,而對r重新賦值:?
????
r=bl;?//用派生類B對象bl對a1的引用變量r賦值

注意?:此時r并不是bl的別名,也不與bl共享同一段存儲單元。它只是b1中基類部分的別名,r與bl中基類部分共享同一段存儲單元,r與b1具有相同的起始地址。

3、如果函數的參數是基類對象或基類對象的引用,相應的實參可以用子類對象。

如有一函數fun:

????void fun(A&r)???????????//形參是類A的對象的引用?
???????
{?cout<<r.num<<endl;}//輸出該引用所代表的對象的數據成員num

????函數的形參是類A的對象的引用變量,本來實參應該為A類的對象。由于子類對象與派生類對象賦值兼容,派生類對象能自動轉換類型,在調用fun函數時可以用派生類B的對象bl作實參: fun(b1);
輸出類B的對象bl的基類數據成員num的值。

???在fun函數中只能輸出派生類中基類成員的值?

4、派生類對象的地址可以賦給指向基類對象的指針變量,也就是說,指向基類對象的指針變量也可以指向派生類對象。

例10?定義一個基類Student(學生),再定義Student類的公用派生類Graduate(研究生),用指向基類對象的指針輸出數據。

本例主要是說明用指向基類對象的指針指向派生類對象,為了減少程序長度,在每個類中只設很少成員。學生類只設num(學號),name(名字)和score(成績)3個數據成員,Graduate類只增加一個數據成員pay(工資)?:

#include <string>
using namespace std;
class Student??????????//聲明Student類?
????
{?public:
???????Student(int,string,float);?//聲明構造函數?
????????
void display();?????//聲明輸出函數?
???????
private:
????????int num;
????????string name;
????????float score; };
Student::Student(int n,string nam,float s)//定義構造函數?
????
{?num=n;
????????name=nam;
????????score=s; }
void Student::display()????//定義輸出函數?
???
{?cout<<endl<<"num:"<<num<<endl;
????cout<<"name:"<<name<<endl;
????cout<<"score:"<<score<<endl; }

class Graduate:public Student?//聲明公用派生類Graduale?
????
{?public:
????????Graduate(int,string,float,float);//聲明構造函數
????????void display();?????//聲明輸出函數?
???????
private:
???????float pay; };???????//工資?
void Graduate::display()????//定義輸山函數?
???
{?Student::display();????//調用Student類的display函數?
????
cout<<"pay="<<pay<<endl; }
Graduate::Graduate(int n,string nam,float s,float p):Student(n,nam,s),pay(p){}
??????? //定義構造函數

int main()
{?Student stud1(1001,"Li",87.5);?????????//定義Student類對象stud1?
?? Graduate grad1(2001,"Wang",98.5,563.5);//定義Graduate類對象grad1?
???
Student *pt=&stud1;???????//定義指向Student類對象的指針并指向studl?
????
pt->display();???????????//調用studl.display函數?
????
pt=&grad1;???????????????//指針指向gradl?
????
pt->display();???????????//調用gradl.display函數?
????
return 0; }

程序的輸出結果:?
????????
num:1001
????????name:Li
????????score:87.5
????????num:2001
????????nume:wang
????????score:98.5

為什么沒有輸出pay的值?

??? 通過本例可以看到:?用 指向基類對象的指針變量指向子類對象是合法的、安全的,不會出現編譯上的錯誤。但在應用上卻不能完全滿足人們的希望,人們有時希望通過使用基類指針能夠調 用基類和子類對象的成員。如果能做到這點,程序人員會感到方便。在下一章就要解決這個問題。辦法是使用虛函數和多態性。

總結

以上是生活随笔為你收集整理的派生类到基类的转换 和基类到派生类的转换的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。