派生類的對(duì)象都含有基類對(duì)象作為其一部分,我們可以將指向派生類型的引用轉(zhuǎn)換為指向它的基類型的引用,像轉(zhuǎn)換指針一樣,我們可以用派生類的對(duì)象初始化或賦值基類對(duì)象,反之卻不行。class base{
public:
};
class derived:public base{
public:
};
int main(void) {
derived obj_d;
base obj_b=obj_d;//賦值運(yùn)算符
base obj_b2(obj_d);//用派生類對(duì)象初始化
derived &ref_d=obj_d;
base &ref_b=ref_d;
base &ref_b2(ref_d);
cout<<"end in main\n";
return EXIT_SUCCESS;
}
程序編譯沒(méi)有錯(cuò)誤,只是會(huì)提示ref_b,ref_b2沒(méi)有使用,如果反過(guò)來(lái)轉(zhuǎn)換基類對(duì)象或引用為派生類型的則會(huì)報(bào)錯(cuò)。
實(shí)際上,這里編譯器并沒(méi)有將派生類對(duì)象或引用“轉(zhuǎn)換”為基類型的,只是用派生類對(duì)象中的基類部分初始化或賦值基類對(duì)象,引用方面,將派生類基類部分的地址傳遞給基類型的引用。
前面在虛函數(shù)實(shí)例時(shí),看到將派生類對(duì)象傳遞給參數(shù)為基類型引用的函數(shù),這時(shí)傳遞的是地址,實(shí)參的派生類對(duì)象還是派生類對(duì)象。
如果是參數(shù)為基類對(duì)象的函數(shù),情況有所不同,實(shí)參派生類對(duì)象的基類部分會(huì)被復(fù)制給一個(gè)函數(shù)體內(nèi)建立的臨時(shí)的基類對(duì)象。
當(dāng)我們用派生類對(duì)象初使化或賦值基類對(duì)象時(shí),有兩種可能:
1.基類中定義了相應(yīng)的構(gòu)造函數(shù)和重載了賦值運(yùn)算符,這時(shí)將會(huì)按照相應(yīng)的函數(shù)進(jìn)行
class derived;
class base{
public:
base(const derived&);
base& operator=(derived &);
};
2.基類中并沒(méi)有定義相關(guān)的函數(shù),與情況1相比,這種情況更為常見(jiàn)。
通常基類中會(huì)有考構(gòu),其參數(shù)為const 基類型引用,考構(gòu)會(huì)幫我們完成派生類對(duì)象初始化或賦值基類型對(duì)象,其中發(fā)生指向派生類的引用轉(zhuǎn)換為基類型的引用。開(kāi)頭的示例程序:
base obj_b=obj_d;//賦值運(yùn)算符
base obj_b2(obj_d);//用派生類對(duì)象初始化,調(diào)用的構(gòu)造函數(shù)
派生類中的基類部分好像被“切割”(slice down)下一樣,賦值給基類對(duì)象。
派生類-基類 轉(zhuǎn)換后的成員訪問(wèn)問(wèn)題
如果是公有派生,轉(zhuǎn)換后,可以訪問(wèn)基類對(duì)象的相應(yīng)成員,如果是保護(hù)或私有派生則不可。
class base{
public:
int pub;
protected:
int pro;
};
class derived:public base{
public:
};
int main(void) {
derived obj_d;
base obj_b=obj_d;//賦值運(yùn)算符
cout<<obj_b.pub<<" "<<endl;
cout<<"end in main\n";
return EXIT_SUCCESS;
}
程序沒(méi)有任何問(wèn)題,輸出結(jié)果為一隨機(jī)值,因?yàn)槲覀儧](méi)有定義任何構(gòu)造函數(shù)為數(shù)據(jù)成員初始化。
如果將派生類型變?yōu)楸Wo(hù)或私有
class derived:protected base{
public:
};
編譯報(bào)錯(cuò) `base' is an inaccessible base of `derived'
而且,私有派生時(shí),其后續(xù)派生的類是不可轉(zhuǎn)換為基類型的,保護(hù)派生可以。
基類-派生類 的轉(zhuǎn)換
無(wú)論是用基類對(duì)象還是引用初始化派生類對(duì)象或引用都是不可以的,基類對(duì)象其所占的內(nèi)存空間中并沒(méi)有派生類所定義的只屬于它自己的那一部分。即使是有一個(gè)基類型的引用,其此時(shí)正好指向一個(gè)派生類對(duì)象,我們也不可將其轉(zhuǎn)換為派生類型的引用,因?yàn)榫幾g時(shí)編譯器檢查的是靜態(tài)類型。