接着上一篇总结访问控制权限的博文,我们将上一篇遗留的继承的访问权限进行总结。


1、首先我先强调一个问题,子类继承了父类除了构造函数和析构函数的所有方法和属性。包括private修饰的属性和方法,这一点是很重要的,有很多人认为私有的不被继承,之所以产生这种误区,是子类中不可用父类的私有属性。

2、类继承后方法的属性变化:

1、使用private继承,父类的protected和public属性在子类中变为private,private属性不变。

2、使用protected继承,父类的protected和public属性在子类中变为protected,private属性不变。

3、使用public继承,父类的protected、public和private属性不发生改变。

强调:private属性被子类继承,但是不能被子类使用。

1、上边只是概括的总结了一下,下来我将分别总结一下。

(1)、对于公有继承:

1、基类成员对其对象的可见性:

公有成员可见,其他不可见。这里是保护成员与私有成员一样不可见。

2、基类成员对派生类的可见性

公有成员和保护成员可见,而私有成员不可见。这里保护成员同于公有成员一样可见。

3、基类成员都派生对象的可见性

公有可见,其他均不可见。

也就是说,在公有继承时,派生类的对象可以访问基类中的公有成员;派生类的成员函数可以访问基类中公有成员和保护成员。

4、同样我这里继续给出测试验证代码:


classBase{public:Base():x(0),y(0),z(0){}~Base(){}public:intx;voidShowBase(){cout<<"IamShowBaseandampublic"<<endl;}protected:inty;voidPrint(){cout<<"IamPrintandamprotected"<<endl;private:voidPrint_Private(){cout<<"IamPint_Private"<<endl;}intz;};classD:publicBase{public:D():a(0),b(0),c(0){}~D(){}inta;voidShow_D(){cout<<"IamShow_Dandpublic"<<endl;//测试公有继承时,父类的公有方法和属性ShowBase();//父类的公有方法x=10;//父类的公有属性cout<<"Base'sx="<<x<<endl;//测试公有继承时,父类的保护方法和属性Print();y=20;cout<<"Base'sy="<<y<<endl;//测试公有继承时,父类的私有方法和属性//Print_Private();//z=30;//cout<<"Base'sz="<<z<<endl;}voidTest(){//验证公有继承再保护方法中Print_D();//验证公有继承再私有方法中fun_private();}protected:voidPrint_D(){cout<<"IamPrint_Dandamprotected"<<endl;//测试公有继承时,父类的公有方法和属性ShowBase();//父类的公有方法x=10;//父类的公有属性cout<<"Base'sx="<<x<<endl;//测试公有继承时,父类的保护方法和属性Print();y=20;cout<<"Base'sy="<<y<<endl;//测试公有继承时,父类的私有方法和属性//Print_Private();//z=30;//cout<<"Base'sz="<<z<<endl;}intb;private:voidfun_private(){cout<<"Iamfun_private"<<endl;//测试公有继承时,父类的公有方法和属性ShowBase();//父类的公有方法x=10;//父类的公有属性cout<<"Base'sx="<<x<<endl;//测试公有继承时,父类的保护方法和属性Print();y=20;cout<<"Base'sy="<<y<<endl;//测试公有继承时,父类的私有方法和属性//Print_Private();//z=30;//cout<<"Base'sz="<<z<<endl;}intc;};voidmain(){Dd1;d1.Show_D();//子类对象可以访问父类的公有成员d1.ShowBase();}


测试结果:



对于每一种情况我都给出了测试案例,并且在测试代码中尽可能多按照我的理解写上了注释。


2、对于保护继承:

1、基类成员对其对象的可见性

公有成员可见,其他不可见。这里是保护成员与私有成员一样不可见。

2、基类成员对派生类的可见性

公有成员和保护成员可见,而私有成员不可见。这里保护成员同于公有成员一样可见。

3、基类成员都派生对象的可见性

公有可见,其他均不可见。

4、同样我这里继续给出测试验证代码:


classBase{public:Base():x(0),y(0),z(0){}~Base(){}public:intx;voidShowBase(){cout<<"IamShowBaseandampublic"<<endl;}protected:inty;voidPrint(){cout<<"IamPrintandamprotected"<<endl;}private:voidPrint_Private(){cout<<"IamPint_Private"<<endl;}intz;};classD:protectedBase{public:D():a(0),b(0),c(0){}~D(){}inta;voidShow_D(){cout<<"IamShow_Dandpublic"<<endl;//测试保护继承时,父类的公有方法和属性ShowBase();//父类的公有方法x=10;//父类的公有属性cout<<"Base'sx="<<x<<endl;//测试保护继承时,父类的保护方法和属性Print();y=20;cout<<"Base'sy="<<y<<endl;//测试保护继承时,父类的私有方法和属性//Print_Private();//z=30;//cout<<"Base'sz="<<z<<endl;}voidTest(){//验证保护继承再保护方法中Print_D();//验证保护继承再私有方法中fun_private();}protected:voidPrint_D(){cout<<"IamPrint_Dandamprotected"<<endl;//测试保护继承时,父类的公有方法和属性ShowBase();//父类的公有方法x=10;//父类的公有属性cout<<"Base'sx="<<x<<endl;//测试保护继承时,父类的保护方法和属性Print();y=20;cout<<"Base'sy="<<y<<endl;//测试保护继承时,父类的私有方法和属性//Print_Private();//z=30;//cout<<"Base'sz="<<z<<endl;}intb;private:voidfun_private(){cout<<"Iamfun_private"<<endl;//测试保护继承时,父类的公有方法和属性ShowBase();//父类的公有方法x=10;//父类的公有属性cout<<"Base'sx="<<x<<endl;//测试保护继承时,父类的保护方法和属性Print();y=20;cout<<"Base'sy="<<y<<endl;//测试保护继承时,父类的私有方法和属性//Print_Private();//z=30;//cout<<"Base'sz="<<z<<endl;}intc;};voidmain(){Dd1;d1.Show_D();//子类对象可以访问父类的公有成员//d1.ShowBase();


运行结果:



3、对于私有继承

1、基类成员对其对象的可见性:

公有成员可见,其他不可见。

2、基类成员对派生类的可见性

公有成员和保护成员可见,而私有成员不可见。这里保护成员同于公有成员一样可见。

3、基类成员都派生对象的可见性

所有成员均不可见。

也就是说,私有继承,基类成员的只能由直接派生类访问,而无法再往下继续访问。

4、同样我这里也给出测试代码:


classBase{public:Base():x(0),y(0),z(0){}~Base(){}public:intx;voidShowBase(){cout<<"IamShowBaseandampublic"<<endl;}protected:inty;voidPrint(){cout<<"IamPrintandamprotected"<<endl;}private:voidPrint_Private(){cout<<"IamPint_Private"<<endl;}intz;};classD:privateBase{public:D():a(0),b(0),c(0){}~D(){}inta;voidShow_D(){cout<<"IamShow_Dandpublic"<<endl;//测试私有继承时,父类的公有方法和属性ShowBase();//父类的公有方法x=10;//父类的公有属性cout<<"Base'sx="<<x<<endl;//测试私有继承时,父类的保护方法和属性Print();y=20;cout<<"Base'sy="<<y<<endl;//测试私有继承时,父类的私有方法和属性//Print_Private();//z=30;//cout<<"Base'sz="<<z<<endl;}voidTest(){//验证私有继承再保护方法中Print_D();//验证私有继承再私有方法中fun_private();}protected:voidPrint_D(){cout<<"IamPrint_Dandamprotected"<<endl;//测试私有继承时,父类的公有方法和属性ShowBase();//父类的公有方法x=10;//父类的公有属性cout<<"Base'sx="<<x<<endl;//测试私有继承时,父类的保护方法和属性Print();y=20;cout<<"Base'sy="<<y<<endl;//测试私有继承时,父类的私有方法和属性//Print_Private();//z=30;//cout<<"Base'sz="<<z<<endl;}intb;private:voidfun_private(){cout<<"Iamfun_private"<<endl;//测试私有继承时,父类的公有方法和属性ShowBase();//父类的公有方法x=10;//父类的公有属性cout<<"Base'sx="<<x<<endl;//测试私有继承时,父类的保护方法和属性Print();y=20;cout<<"Base'sy="<<y<<endl;//测试私有继承时,父类的私有方法和属性//Print_Private();//z=30;//cout<<"Base'sz="<<z<<endl;}intc;};classC:publicD{public:C(){}~C(){}voidc_fun(){cout<<"Iamc_funandpublic"<<endl;//测试继承时,父类的公有方法和属性ShowBase();//父类的公有方法x=100;//父类的公有属性cout<<"Base'sx="<<x<<endl;//测试保护继承时,父类的保护方法和属性Print();y=200;cout<<"Base'sy="<<y<<endl;//测试保护继承时,父类的私有方法和属性//Print_Private();//z=300;//cout<<"Base'sz="<<z<<endl;}protected:private:};voidmain(){Dd1;d1.Show_D();Cc1;//保护继承时,当再次被继承时,即使时公有继承,对象将不能再访问//c1.ShowBase();//子类对象可以访问父类的公有成员//d1.ShowBase();}


测试结果:


细心同学就会发现,私有继承和保护继承的测试结果不是一样吗?事实上是不一样的,我在私有继承的测试代码中再加了一个类,C类,并且C类继承于D类,我们可以从测试结果中看出,当D类私有继承时,C类将不能访问Base类的任何成员,当然C类的对象更不能访问,而如果D类保护继承与Base时,C类可以访问Base的公有、保护成员,当然对象也不能访问。


以上就是笔者对继承中访问控制权限的理解,并且给出了测试代码帮助理解,希望可以帮助到大家。