第二章继承与派生
這節課,我們來學習繼承。
當從基類派生出新類時,可以對派生類作如下幾個變化:
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函數如下:
代碼下載:http://pan.baidu.com/share/link?shareid=2883935448&uk=3189484501
訪問規則
私有派生例子:
#include <iostream>
usingnamespacestd;
//程序分析:
//在這個例子中,基類的公有成員iVarA通過私有派生成了派生類的私有成員,所以當Derived類再派生其子類時,iVarA是不可訪問的。
//由于私有派生這個特點,因此在實際工作中私有派生很少使用。
代碼下載: 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
多重繼承例子
多重繼承中構造函數和析構函數的調用順序
代碼下載地址: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
轉載于:https://blog.51cto.com/7097095/1224314
總結
- 上一篇: 立体成像(1)
- 下一篇: 《失业的程序员》(六):加班