在上麵的代碼中,我們調用基類Location中的公有成員函數GetX()和GetY(),實現在派生類Rectangle的成員函數show()中,訪問基類的私有數據成員x和y。
下麵對在派生類的成員函數中訪問基類成員再做兩點說明:
1.基類的私有成員
前麵我們說過,無論是公有派生,還是私有派生,基類的私有成員都成為派生類的不可訪問成員。所謂不可訪問成員,是指不僅不能在程序的其它地方訪問,即使該類的自身成員函數也不能訪問,因此,派生類的成員函數不能訪問基類的私有成員。
2.基類的公有成員
在公有派生中,基類的公有成員成為派生類的公有成員,派生類的成員函數自然能訪問這些成員。
在私有派生中,基類的公有成員成為派生類的私有成員,既然已經成為派生類的成員,派生類的成員函數也就有權訪問這些成員。
總之,無論是公有派生,還是私有派生,派生類的成員函數都可以訪問基類的公有成員。
3.不可訪問成員
在繼承的關係中,基類和派生類是相對而言的。沒有任何基類的類叫根類,它不是從別的類派生出來的。在根類中,沒有成員是“不可訪問的”。對於根類來說,唯一可能訪問的權限是private、protected>public。在派生類中,“不可訪問的”這一訪問級別才可能出現。不可訪問成員總是由基類繼承來的,它要麼是基類的不可訪問成員,要麼是基類的私有成員。
四、保護派生
除了public和private關鍵字外,Visual C++提供了第三個訪問控製說明符:protected。由關鍵字protected說明的成員稱為保護成員。
保護成員和私有成員很相似,隻是它們可以被派生類的成員函數訪問。
在繼承的關係下,基類的私有成員成為派生類的不可訪巧成母。如果需要某些數據成員僅可由派生類訪問,可以將它們說明為protected。
在這個例子中,私有成員b對於派生類的成員函數firnc()來說是不可訪問的,但保護成員a是可以訪問的。然而,在基類和派生類之外,保護成員仍然是不可訪問的。
公有派生下,基類的保護成員成為派生類的保護成員;私有派生下,基類的保護成員成為派生類的私有成員。
注意,關鍵字piotected應謹慎使用。如果基類的保護部分重寫了,那麼,使用了保護成員的所有派生類也必須重新編寫。
在定義派生類時,如果訪問控製使用關鍵字protected,這種繼殺關係稱為保護派生。在使用編程時,大多數的派生類都是經由公有派生產生,私有探生與保護派生一般不被使用。私有派生雖然不常用,但它確實是VtoalC++的一個優秀特色,而保護派生,其作用對予初學者來說不易參捶,建議不要使用。
五、類的友員沒有繼承性
類的友元雖然可以訪問類的私有成員,但是,當編譯舞調用友函數時,並沒有向它傳遞thi8指針,因此,類的友元不屬於類的成員。
一個類的友元並非該類的成員之一,因此在繼承的過程中,它不能被派生類繼承。當類的友元希望可以再重複使用時,則必須將其設計為類的成員,才有用能被繼承使用。
8.3公有派生類與基類的轉換
在繼承的關係下,公有派生類的對象可以直接賦值給其基類的對象,而不須經過任何轉換。
在上麵的代碼中,派生類Child是塞類parent的公有派生,派生類對象child的內存布局應該包括兩部分:前一部分是基類Location的成員,後一部分是派生類Hectangle的自身成員。時,編譯器把派生類對象child中的基類成員的內容拷貝給基類對象P—t,而忽略了對象child的派生類自身的成員部分,事實上,不僅公有派生類對象可以直接賦值結其基類的對象,而且公有派生類對象指針的地址可以直接賦值給指向基類對象的指針變量,基類的對象的引用可以直接引用公有派生類對象。
這些轉換是由編譯器根據內建的規則來執行的,無須由用戶明確賦值。Visual C++的編譯器首先將派生類的各種類型對象轉換為基類中對應的型態,然後賦,值給基類所定義的對象。
上麵的賦值轉換都是由派生類到基類,Visual C++的編譯器之所以允許這樣的賦值轉換,是因為派生類對象中含有一份基類的對象,使得這樣的賦值語句是安全的。相反,若將一個基類的對象、引用或指針給派生類對象,則必須明確使用強製轉換的方式來通知編譯器如何進行轉換。
這樣,編譯器才知道如何進行轉換。這樣的賦值雖然編譯時不會出現問題,在使用上卻是危險的,此時指針雖然是屬於派生類的型態,其實麻內容可能隻含有基類的成員。因此,若使用時調用了派生類中自身定義的成員,將發生危險。
對於私有派生類和保護派生類,它們不能自動轉化成它們的基類,所以不具備公有派生類的上麵的性質。
8.4繼承下派生類構造函數的設計
一、派生類構造函數的初始化
在繼承的關係下,派生類繼承了基類中所肴非區的數據成員與成員函數,但對於基類的構造函數,是不能繼承的,不論該構造函數是否位於public區。
因此,設計派生類的構造函數時,基類的構造函數必須由派生類的構造函數負責調用,也就是說,派生類的構造函數除了負責本1始化自身的數據成員外,也必須負責基類中數據成員的初始化。當為派生類編寫構造函數時,可以利用對象成員的成員初始化表類似的語法規則,指定一個“成員初始化表”。結合本例,我們對派生類構造函數的初始化做兩點說明:
1.在派生類構造函數的成員初始化表中,為基類的構造函數傳遞參數的一般形式:派生類構造函數基類構造函數下派生類名(參數表):基類名(參數表)其中,派生類構造函數與基類構造函數之間用冒號隔開,基類的參數表可以是派生類構造函數參數表的部分或全部,參數表中可以包含任何當時有效的表達式,包括函數和變量。
在上麵的例子中,派生類構造函數Rectangle有四個參數,其中前兩個參數xx,yy傳遞給基類的構造函數Location,後兩個參數w和h用來初始化派生類自身函數成員。
2.成員初始化表隻可以出現在派生類構造函數的定義部分,而不能在派生類構造函數的原型後出現。