一、公有繼承(public inheritance)
1 #include <iostream> 2 using namespace std; 3 4 class A{ 5 public: 6 A():x(10),y(20){} 7 A(int x){this->x = x;} 8 int getx(){return x;} 9 int gety(){return y;} 10 int getu(){return u;} 11 protected: 12 int y; 13 private: 14 int x; 15 int u; 16 }; 17 //class B:public A{ //訪問公有、保護成員 18 // 19 //}; 20 class B:public A{ //通過A中的公有成員函數才能訪問A中的私有成員,派生類的成員或者派生類的對象都無法直接訪問基類私有成員 21 public: 22 // int getx(){return x;} //錯誤,直接用派生類的成員訪問基類私有成員 23 // int getx(){return A::getx();} 24 int getx(){return 30;} //改造基類成員函數 25 void sety(){y = 100;} //直接調用基類保護成員並修改 26 }; 27 int main(){ 28 B b; 29 cout<<"原始的x:"<<b.A::getx()<<endl; //調用基類的同名函數 30 cout<<"改造后的x:"<<b.getx()<<endl; //調用改造后的函數 31 32 cout<<"保護成員y:"<<b.gety()<<endl; 33 b.sety(); 34 cout<<"在派生類中修改y值:"<<b.gety()<<endl; 35 cout<<"私有成員u:"<<b.getu()<<endl; //公有繼承可以通過派生類的對象訪問基類繼承的公有成員 36 // cout<<B::x<<endl; //錯誤,無法通過派生類成員訪問基類私有成員 37 // cout<<b.y<<endl; //錯誤, 通過對象無法訪問保護成員 38 return 0; 39 }
執行結果:

理解:
公有繼承方式:
在派生類內部:
1、 派生類成員可以直接訪問基類的公有和保護類成員【上面代碼23、25行】
2、 當然,如果想拓展繼承來的函數可以進行改造,改造是可以同名的,
在接下來用對派生類的對象調用該函數時就會使用改造后的函數【上面代碼24,29行】,
在后來的調用調用中仍然可以調用基類的未改造的函數【代碼28行】
在派生類外部:
1、通過派生類的對象可以訪問基類的公有成員(!這里只能訪問公有成員,連保護成員都不可以訪問)【上面代碼35、36行】
2、無論是派生類的成員還是對象都無法直接訪問基類私有成員【上面代碼36、37行】
需要注意的是:如果派生類的成員函數與基類的成員函數且你想使用基類的那個函數功能,你需要用 '' 類名::'' 這種方式實現。(三種繼承方式都是這樣)
【上面代碼23行】
二、私有繼承(private inheritance)
1 #include <iostream> 2 using namespace std; 3 4 class A { 5 public: 6 A() : x(10), y(20) {} 7 int getx() { return x; } 8 int gety() { return y; } 9 int getu() { return u; } 10 protected: 11 int y; 12 private: 13 int x; 14 int u; 15 }; 16 17 18 class B : private A { 19 public: //因為基類的公有、保護成員作為派生類的私有成員,派生類的成員不能直接訪問它們, 20 int getx() { return A::getx(); } //只能通過成員函數調用它們 21 22 int getyy() { return gety(); } 23 24 int getyyy(){return y;} //派生類成員中可以直接訪問基類繼承的公有和保護成員 25 26 }; 27 28 int main() { 29 B b; 30 cout <<"x的值:" <<b.getx() << endl; 31 cout <<"y的值:"<< b.getyy() << endl; 32 cout<<"y的值:"<<b.getyyy()<<endl; 33 // cout<<b.getu()<<endl; //錯誤,私有繼承無法通過派生類對象訪問基類成員 34 return 0; 35 }
執行結果:

理解:
私有繼承方式:
在類的內部:
1、由於基類的公有成員和保護成員變成派生類的私有成員,派生類的成員可以直接訪問它們【上面代碼20、24行】
在類的外部:
1、派生類外部無法通過對象直接訪問基類的公有成員和保護成員(這是與公有繼承的一個差別)【上面代碼33行】
在派生內外部: 都無法直接訪問基類私有成員
三、保護繼承(protected inheritance)
1 #include <iostream> 2 using namespace std; 3 4 class A{ 5 public: 6 A():x(10),y(20){} 7 int getx(){return x;} 8 int gety(){return y;} 9 int getu(){return u;} 10 protected: 11 int y; 12 private: 13 int x; 14 int u; 15 }; 16 class B:protected A{ 17 public: 18 int getxx(){return getx();} //派生類成員可以直接訪問繼承來的公有成員【與公有繼承一樣】 19 int getyy(){return y;} 20 }; 21 int main(){ 22 B b; 23 cout<<"x的值:"<<b.getxx()<<endl; 24 cout<<"y的值:"<<b.getyy()<<endl; 25 26 // cout<<b.getx()<<endl; //通過派生類的對象無法直接訪問基類成員【與私有繼承一樣】 27 // cout<<b.y<<endl; 28 }
執行結果:

理解:
保護繼承方式:
在類內部:
1、繼承的公有、保護成員以保護成員存在(存在方式與公有繼承的以公有成員存在方式不同),派生類的其它成員可以直接訪問
(這一點與公有、私有繼承一致)。【上面代碼18、19行】
在類外部:
1、通過派生類對象無法直接訪問繼承的公有、保護成員【上面代碼26、27行】(與私有繼承一樣)
在派生類內外部:基類的私有成員都無法直接訪問
1 #include <iostream> 2 using namespace std; 3 4 class A{ 5 public: 6 A():x(10),y(20){} 7 int getx(){return x;} 8 int gety(){return y;} 9 int getu(){return u;} 10 protected: 11 int y; 12 private: 13 int x; 14 int u; 15 }; 16 class B:protected A{ //直接繼承時 使用保護繼承 再看二次繼承的效果 17 public: 18 int getxx(){return getx();} 19 int getyy(){return y;} 20 }; 21 //二次繼承無論是私有還是保護繼承,二次派生類都可以間接訪問初始基類A的公有、保護成員 22 //class C:private B{ 23 //public: 24 // int getA_x(){return getx();} 25 // int getA_y(){return y;} 26 //}; 27 class D:protected B{ 28 public: 29 int getA_x(){return getx();} 30 int getA_y(){return y;} 31 };
再看:直接繼承時使用私有繼承
代碼如下:
1 #include <iostream> 2 using namespace std; 3 4 class A{ 5 public: 6 A():x(10),y(20){} 7 int getx(){return x;} 8 int gety(){return y;} 9 int getu(){return u;} 10 protected: 11 int y; 12 private: 13 int x; 14 int u; 15 }; 16 class B2:private A{ //直接繼承時 使用私有繼承 再看二次繼承的效果 17 public: 18 int getc_x(){return getx();} 19 int getc_y(){return gety();} 20 }; 21 //二次繼承無論時私有還是保護繼承,都無法間接使用初始基類A的成員 22 class C2:private B2{ 23 public: 24 // int getA_x(){return getx();} //錯誤,無法間接訪問從初始基類A繼承的成員 25 }; 26 class D2:protected B2{ 27 public: 28 // int getA_x(){return getx();} //錯誤,無法間接訪問從初始基類A繼承的成員 29 };
上面兩塊代碼,我們主要看直接派生類 B&B2 的繼承方式 and C&C2 、D&D2 能否調用初始基類A的成員
我們發現當直接派生類為私有繼承時,通過它在派生的類無法間接訪問最初基類成員,
而直接派生類為保護繼承時,再通過它派生的成員則可以間接訪問最初基類的公有、保護成員。
===============================================================================================================
以上為現階段學習理解,如有錯誤,希望指正:)
