我們先看乙個例子:
class base
;class derived1 : public base
;class derived2 : public base
;class mi : public derived1,public derived2
;
上面的例子,我們定義了類層次結構。當執行下面的語句時將會產生編譯錯誤:
mi mi ;
string dancer("nijingsky") ;
mi.print(dancer) ;
為什麼會出現編譯錯誤呢?問題是對於類mi的物件而言,可見的print函式是:
void print(complex) const ;
因此,編譯器無法將乙個string物件轉換成complex物件。為什麼可見的print函式只有這乙個呢?這是因為print函式並沒有被過載。因為「過載函式解析程式」有乙個限制:過載的函式必須是位於同乙個scope(區域)中。在這裡就是,過載的函式必須位於同乙個class中。所以,在類mi中,可見的print函式只有乙個。因為其他的print函式並沒有與其在同乙個class中。
如何解決這個問題呢?類mi內必須有乙個print(string);
void print(string) const ;
並讓這個函式呼叫基類base的print(string)。但是此處有乙個問題:由於我們並沒有使用虛擬繼承,編譯器並不知道我們究竟希望通過derived1還是derived2來呼叫print函式。所以,我們又修改derived1,提供它自己的print(string)來呼叫base的print(string)。
void derived1::print(string s)
於是mi的print(string)函式可以寫成:
void mi::print(string s)
注意,我們不能寫成:
void mi::print(string s)
因為derived1::base::print(s)被解釋為取用derived1內的巢狀類base內的成員函式print。也就是上述語法指的不是繼承關係,而是某個型別和巢狀類的關係。如果寫成:
void mi::print(string s)
也無法正常工作,因為base不是mi的直接基類。注意這一點:就是派生類不能直接呼叫間接基類的成員函式。只能呼叫直接基類的成員函式。要想呼叫間接基類的函式,必須先通過其直接基類,然後再在其直接基類中呼叫該間接基類。 函式過載和虛函式繼承
include class cbase void g float x class cberived public cbase void g float x void main 輸出結果 cberived f 函式列印 整數 3 cberived g 函式列印 浮點小數 6.000000 cberiv...
過載函式的繼承
在基類中過載的函式,派生類可以重定義所繼承的0個或多個版本。如果派生類想通過自身型別使用的過載版本,則派生類必須要麼重定義所有過載版本,要麼乙個也不重定義。但有時類需要僅僅重定義乙個過載集中某些版本的行為,並且想繼承其它版本的含義。這時,可以用using宣告講基類所有的過載例項載入到派生類中,派生類...
c 的繼承關係和函式過載
主要關注兩個方面 1 子類和基類之間變數重名 2 函式重名,但是形參列表不同 第乙個 眾所周知,子類繼承基類的所有變數,那麼如果子類的成員變數和父類的某一變數重名,通過父類的引用或者指標訪問的變數是父類的變數還是子類的呢?寫個程式測之。結果為 4 這說明,在編譯期間,基類的指標取變數值為基類自己的變...