C++学习笔记——访问控制说明符

访问说明符(public,protected,private)类型:

  • 类成员访问说明符
  • 继承访问说明符

 

继承访问说明符说明了派生类中基类部分成员的继承方式。

  • 通过public继承:派生类中基类部分成员的访问说明符在基类中为public或protected的,在派生类中类型保持不变,private的成员不可访问
  • 通过protected继承:派生类中基类部分成员的访问说明符在基类中为public或protected的,在派生类中类型为protected,private的成员不可访问
  • 通过private继承:派生类中基类部分成员的访问说明符在基类中为public或protected的,在派生类中类型为private,private的成员不可访问

(不可访问是指不能直接通过子类访问,但可以通过父类的成员访问,不可访问属于private,但是不能通过第1级访问去访问)

 

现在,假设将访问的用户分为2级:

1.类内访问

2.类的用户(可以理解成通过类的对象来访问)

注:类内访问主要是指类的成员函数

对于1级用户来说,可以访问除不可访问外的所有(public,protected,private)成员。2级用户只能访问public的成员。

(这里被访问的成员都是指类成员访问说明符修饰的类成员)

 

下面通过实验来看看:

首先是基类:

/*********************
**** Base Class
**********************/
#include <string>
 
class Base{
public:
       //Constructor
       Base():
              base_public_string("I'm base_public_string"),
              base_protected_string("I'm base_protected_string"),
              base_private_string("I'm base_private_string")
              {}
       Base(std::stringpub,std::string pro,std::string pri):
              base_public_string(pub),base_protected_string(pro),base_private_string(pri){}
      
       std::string base_public_string;              //public string member
 
protected:
       std::string base_protected_string;   //protect string member
private:
       std::string base_private_string;             //private string member
};

包括两个public的构造函数和3个string类型的成员(public,protected,private各一个)。

 

然后是通过public继承的类:

/*********************
**** PubDerv Class
**********************/
#include <iostream>
 
class PubDerv:public Base{
public:
       PubDerv():Base(){}
       PubDerv(std::string pub,std::string pro,std::string pri):Base(pub,pro,pri){}
       void pub_printParentMem()
       {
              std::cout<<base_public_string<<std::endl;
              std::cout<<base_protected_string<<std::endl;
              //std::cout<<base_private_string<<std::endl;
       }
protected:
       void pro_printParentMem()
       {
              std::cout<<base_public_string<<std::endl;
              std::cout<<base_protected_string<<std::endl;
              //std::cout<<base_private_string<<std::endl;
       }
private:
       void pri_printParentMem()
       {
              std::cout<<base_public_string<<std::endl;
              std::cout<<base_protected_string<<std::endl;
              //std::cout<<base_private_string<<std::endl;
       }
};


 

通过protected继承的的类:

/*********************
**** ProDerv Class
**********************/
#include <iostream>
 
class ProDerv:protected Base{
public:
       ProDerv():Base(){}
       ProDerv(std::string pub,std::string pro,std::string pri):Base(pub,pro,pri){}
       void pub_printParentMem()
       {
              std::cout<<base_public_string<<std::endl;
              std::cout<<base_protected_string<<std::endl;
              //std::cout<<base_private_string<<std::endl;
       }
protected:
       void pro_printParentMem()
       {
              std::cout<<base_public_string<<std::endl;
              std::cout<<base_protected_string<<std::endl;
              //std::cout<<base_private_string<<std::endl;
       }
private:
       void pri_printParentMem()
       {
              std::cout<<base_public_string<<std::endl;
              std::cout<<base_protected_string<<std::endl;
              //std::cout<<base_private_string<<std::endl;
       }
};


 

通过private继承的类:

/*********************
**** PriDerv Class
**********************/
#include <iostream>
 
class PriDerv:private Base{
public:
       PriDerv():Base(){}
       PriDerv(std::string pub,std::string pro,std::string pri):Base(pub,pro,pri){}
       void pub_printParentMem()
       {
              std::cout<<base_public_string<<std::endl;
              std::cout<<base_protected_string<<std::endl;
              //std::cout<<base_private_string<<std::endl;
       }
protected:
       void pro_printParentMem()
       {
              std::cout<<base_public_string<<std::endl;
              std::cout<<base_protected_string<<std::endl;
              //std::cout<<base_private_string<<std::endl;
       }
private:
       void pri_printParentMem()
       {
              std::cout<<base_public_string<<std::endl;
              std::cout<<base_protected_string<<std::endl;
              //std::cout<<base_private_string<<std::endl;
       }
};



       

为了方便说明问题。这3个子类除了3个打印函数外,未定义自己的成员。

注意到3个子类的3个打印函数都相同,都是访问父类的3个string成员变量。

 

先来第1级访问(类内访问):

1.      不可访问成员:

父类的私有成员不管以什么方式被继承都是不可访问。可以看到访问base_private_string的代码被注释掉了。因为如果不注释掉,由于不可访问的成员不能由子类直接访问,所以编译时会报错,如下:

以PubDerv为例,3个打印函数访问父类私有变量base_private_string,编译时报错

 

2.      public,protected,private成员:

而父类的公有成员和保护成员由于继承方式不同,在子类中的访问说明符也不同(具体见前面的表格),但是不管是继承下来后属于哪类,对于第1级访问来说,这些成员都能被访问。因此3个子类对父类的公有成员和保护成员都能访问(编译未出错已经说明问题)

 

然后是第2级访问(类的用户):

main.cpp:

#include <iostream>
#include "Base.h"
#include "PubDerv.h"
#include "ProDerv.h"
#include "PriDerv.h"
using namespace std;
 
void main()
{
       PubDerv pubDerv;
       ProDerv proDerv;
       PriDerv   priDerv;
 
       cout<<"pubDerv:"<<endl;
       cout<<pubDerv.base_public_string<<endl;
       cout<<pubDerv.base_protected_string<<endl;
       cout<<pubDerv.base_private_string<<endl;
      
       /*
       cout<<"proDerv:"<<endl;
       cout<<proDerv.base_public_string<<endl;
       cout<<proDerv.base_protected_string<<endl;
       cout<<proDerv.base_private_string<<endl;
       */
 
       /*
       cout<<"priDerv:"<<endl;
       cout<<priDerv.base_public_string<<endl;
       cout<<priDerv.base_protected_string<<endl;
       cout<<priDerv.base_private_string<<endl;
       */
 
       /*
       cout<<"pubDerv:"<<endl;
       pubDerv.pub_printParentMem();
       cout<<"proDerv:"<<endl;
       proDerv.pub_printParentMem();
       cout<<"priDerv:"<<endl;
       priDerv.pub_printParentMem();
       */
}


先试图通过PubDerv的对象访问从父类继承来的3个string,在编译前可以想象结果:由与第2级访问只能访问公有成员,而3个string中只有base_public_string继承之后认识公有的,所以对另外两个string的访问会报错:

注释掉则可顺利编译运行:

 

对于proDerv,由于从父类继承来的2个string为protected,1个为不可访问,因此都不能通过2级访问去访问。

同理priDerv由于从父类继承来的2个string为private,1个为不可访问,也都不能通过2级访问去访问。

 

若要通过2级访问访问public和不可访问以外的成员,则只能通过2级访问访问public成员,间接通过1级访问(public成员)去访问:

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值