您好,登錄后才能下訂單哦!
這節課,我們來學習繼承。
當從基類派生出新類時,可以對派生類作如下幾個變化:
1、可以增加新的成員函數。
2、可以增加新的成員變量。
3、可以重新定義已有的成員函數。
4、可以改變現有的成員屬性。
我們先來學習一個簡單的派生例子
//這是一個簡單的派生例子
首先,創建一個Location類
Location.h文件如下:
#include <iostream> using namespace std; class Location { private: int iPointX; public: void setPointX(int _iPointX) { iPointX = _iPointX; } void showX() { cout<<"X="<<iPointX<<endl; } };
再創建一個Rectangle類
Rectangle.h文件如下:
#include <iostream> #include "Location.h" //此處可以不寫因為可以繼承 //using namespace std; class Rectangle:public Location { private: int iHight; public: void setHight(int _iHight) { iHight = _iHight; } void showH() { cout<<"H = "<<iHight<<endl; } };
main函數如下:
#include "Rectangle.h" int main(int argc, const char * argv[]) { Rectangle rect; rect.setPointX(10); rect.setHight(20); rect.showX(); rect.showH(); return 0; }
代碼下載:http://pan.baidu.com/share/link?shareid=2883935448&uk=3189484501
訪問規則
私有派生例子:
#include <iostream>
usingnamespacestd;
//程序分析:
//在這個例子中,基類的公有成員iVarA通過私有派生成了派生類的私有成員,所以當Derived類再派生其子類時,iVarA是不可訪問的。
//由于私有派生這個特點,因此在實際工作中私有派生很少使用。
class Base { public: int iVarA; Base() { iVarA = 10; } }; class Derived:private Base { public: int iVarC; Derived() { iVarC = 30; } void show() { cout<<iVarA<<" "<<iVarC<<endl; } }; int main(int argc, constchar * argv[]) { Derived derObj; derObj.show(); return0; }
代碼下載: http://pan.baidu.com/share/link?shareid=3533495783&uk=3189484501
保護派生
#include <iostream> using namespace std; //程序分析: //在保護派生中,基類的私有和不可訪問成員在派生類中是不可訪問的成員在派生類中是不可訪問的,基類的保護成員繼續是保護的,而基類的公有成員在派生類中則變為保護的。 class Base { public: int iVarA; Base() { iVarA = 10; } }; class Derived:protected Base { public: int iVarC; Derived() { iVarC = 30; } void show() { cout<<iVarA<<" "<<iVarC<<endl; } }; class Temp { public: void tempShow() { Derived tempD; //下面這行代碼報錯 雖然它在Derived的父類即Base類是公有的,但Derived類通過protected繼承 因此其繼承來的也會變為protected 所以其他類不能直接訪問 // tempD.iVarA = 10; } }; int main(int argc, const char * argv[]) { Derived derObj; derObj.show(); return 0; }
下載地址:http://pan.baidu.com/share/link?shareid=792966415&uk=3189484501
多重繼承例子
#include <iostream> //類C是從類A和類B中共同派生出來的。類C從類A公有派生,因此,類A的中公有函數setA和showA在類C中都是公有。 //類C從類B中私有派生,所以類B中的公有函數,在類C中就是私有的。 using namespace std; class A { private: int iVarA; public: void setA(int _iVarA) { iVarA = _iVarA; } void showA() { cout<<"iVarA:"<<iVarA<<endl; } }; class B { public: int iVarB; void setB(int _iVarB) { iVarB = _iVarB; } void show() { cout<<iVarB<<endl; } }; class C:public A ,private B { private: int iVarC; public: void setC(int _iVarA,int _iVarB,int _iVarC) { setA(_iVarA); setB(_iVarB); iVarC = _iVarC; } void showC() { cout<<"iVarC:"<<iVarC<<endl; } }; int main(int argc, const char * argv[]) { C cObj; cObj.setC(1, 2, 3); cObj.showA(); cObj.showC(); return 0; }
多重繼承中構造函數和析構函數的調用順序
#include <iostream> using namespace std; class A { protected: int iVarA; public: A(int _iVarA) { iVarA = _iVarA; cout<<"Construction A,iVarA = "<<iVarA<<endl; } ~A() { cout<<"Destorying A,iVarA="<<iVarA<<endl; } }; class B:public A { private: A objA; int iVarB; public: //在派生類中對繼承的基類成員的初始化,需要由派生類的構造函數調用基類的構造函數來完成,這里可以用成員初始化列表來完成,這和初始化對象成員有類似之處。 //B(派生類的參數列表):A(基類參數列表1),objA(基類參數列表2) //冒號后面的構造函數成員初始化列表,每一個基類的構造函數用逗號隔開,每項由基類名以及括號內的參數列表組成,參數列表給出所調用的構造函數以及所需的參數,如果某個類使用的是無參數或者是缺省的構造函數,則該項可以不在成員初始化列表中出現。 //當說明一個A類的對象時,首先調用基類的構造函數,對基類成員進行初始化,然后才執行派生類A自身的構造函數,如果某個基類仍然是一個派生類,則這個過程遞歸進行。當該對象注銷時,析構函數的執行順序和執行構造函數的順序正好相反。 //如果派生類中還有對象成員,則對對象成員的構造函數的調用,仍然要在初始化列表中完成。 B(int _iVarB,int _iVarA,int _objA):A(_iVarA),objA(_objA) { iVarB = _iVarB; cout<<"Construction B,iVarB = "<<iVarB<<endl; } ~B() { cout<<"Destorying B, iVarB = "<<iVarB<<endl; } }; int main(int argc, const char * argv[]) { // insert code here... //如果有繼承,基類的構造函數最先調用。 B(1,4,5); return 0; }
代碼下載地址:http://pan.baidu.com/share/link?shareid=1053220775&uk=3189484501
多重繼承和雙層繼承
#include <iostream> using namespace std; class Base { public: Base() { cout<<"Construction Base"<<endl; } ~Base() { cout<<"Destorying Base"<<endl; } }; class A { public: A() { cout<<"Construction A"<<endl; } ~A() { cout<<"Destorying A"<<endl; } }; class B:public Base { public: B() { cout<<"Construction B"<<endl; } ~B() { cout<<"Destorying B"<<endl; } }; class C { public: C() { cout<<"Construction C"<<endl; } ~C() { cout<<"Destorying C"<<endl; } }; class Object:public A ,public B , public C { public: Object() { cout<<"Construction Object"<<endl; } ~Object() { cout<<"Destorying Object"<<endl; } }; //在多重繼承中先執行最先繼承的對象 例如:本例中的A //在雙繼承中例如本例中的B類 B類是繼承自 Base 所以會先執行Base //在析構函數的執行順序與構造函數的執行順序相反 int main(int argc, const char * argv[]) { // insert code here... Object obj; return 0; }
代碼下載: http://pan.baidu.com/share/link?shareid=1098289671&uk=3189484501
多重繼承中的二義性
#include <iostream> using namespace std; class A { public: void Show() { cout<<"A"<<endl; } }; class B { public: void Show() { cout<<"B"<<endl; } void Print() { cout<<"Print()B"<<endl; } }; //多重繼承是指同時繼承多個,例如如下: class Object:public A,public B { public: void Print() { cout<<"ObjectA||B"<<endl; } void ObjectShowA() { A::Show(); } void ObjectShowB() { B::Show(); } }; //如果一個類是由兩個以上的類派生出來的,那么對基類成員的訪問必須是無二以性的。但是如果基類中含有相同名稱的成員,則訪問時可能產生二義性。 int main(int argc, const char * argv[]) { Object obj; //下面注釋的這種寫法會報錯因為會存在二義性 // obj.Show(); obj.A::Show(); obj.Print(); obj.B::Show(); return 0; }
代碼下載: http://pan.baidu.com/share/link?shareid=1143818360&uk=3189484501
多層繼承的二義性
#include <iostream> using namespace std; //多層繼承: 如果一個派生類從多個基類中派生,并且這些基類又有一個共同的基類,則在這個派生類中訪問這個共同的基類中的成員時可能出現二義性。 class Base { public: int iBaseData; }; class A:public Base { public: int iAData; }; class B:public Base { public: int iBData; }; class Object:public A,public B { public: int iObjectData; }; int main(int argc, const char * argv[]) { Object obj; obj.A::iBaseData = 10; obj.B::iBaseData = 20; cout<<"obj.A::iBaseData = "<<obj.A::iBaseData<<endl; cout<<"obj.B::iBData = "<<obj.B::iBaseData<<endl; return 0; }
代碼下載: http://pan.baidu.com/share/link?shareid=1208687701&uk=3189484501
虛基類
#include <iostream> using namespace std; //很顯然當出現上節中的兩層繼承時,程序可能會出現二義性,如果能使這個公共基類只產生一個成員實例的話,很顯然就可以解決這個二義性的問題了,這時我們可以將這個基類說明虛基類的方式來解決這個問題,這就要求在Base類派生新類時,使用關鍵字virtual將Base類說明為虛基類 class Base { public: int iBaseData; void Print() { cout<<"iBaseData = " << iBaseData<<endl; } }; class A:virtual public Base { public: int iAData; void Print() { cout<<"In A iBaseData"<<iBaseData<<endl; } }; class B:virtual public Base { public: int iBate; void Print() { cout<<"In B iBaseData = "<<iBaseData<<endl; } }; class Object:public A , public B { public: int iObjectData; void Print() { cout<<"In Object iBaseData = "<<iBaseData<<endl; } }; //虛擬類可以使多層繼承中公共基類只產生一個實例,即在類Object中,Base類只有一個實例。 //這時obj.A::iBaseData == obj.B::iBaseData == obj.Object::iBaseData int main(int argc, const char * argv[]) { Object obj; obj.iBaseData = 1000; obj.A::Print(); obj.B::Print(); obj.Base::Print(); obj.Print(); //繼承的幾點總結: //能用組合則不用繼承 //繼承的層數小于等于4層。 //盡量避免使用多重繼承 return 0; }
代碼下載: http://pan.baidu.com/share/link?shareid=1294366574&uk=3189484501
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。