C++ 中三种继承方式的理解

一、有继承(public inheritance)

   1.概念:当类的继承方式为公有继承时,基类的公有成员保护成员访问属性在派生类中不变,而基类的私有成员不可以直接访问
   
实验一下:
 
我们用代码实现对概念的理解,如下:
 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.概念:当类的继承方式为私有继承时,基类的公有成员保护成员都以私有成员身份出现在派生类中,而基类的私有成员在派生类中不可直接访问。
 
实验一下:
 
我们仍然使用代码来实现对概念的理解,如下:
 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.概念:保护继承中,基类的公有成员保护成员以保护成员的身份出现在派生类中,而基类的私有成员不可直接访问。
   
实验一下:
 
我们继续用代码实现对概念的理解,如下:
 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的成员

我们发现当直接派生类为私有继承时,通过它在派生的类无法间接访问最初基类成员,

而直接派生类为保护继承时,再通过它派生的成员则可以间接访问最初基类的公有、保护成员。

 


===============================================================================================================

以上为现阶段学习理解,如有错误,希望指正:)

posted @ 2019-10-11 21:39  果冻小布丁  阅读(1102)  评论(0编辑  收藏  举报