c++继承,访问控制

本文详细介绍了C++中的继承访问控制,包括类对象访问、类内访问以及不同继承方式下基类成员在派生类中的访问权限。强调了无论继承方式如何,基类的private成员在派生类中都不能直接访问,而public和protected成员的访问权限受到继承方式的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

【代码1】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class  Base{
     //其他内容
public :
     int  BaseFunPb(){ return  m_nPb;}
     int  BaseFunPt(){ return  m_nPt;}
     int  BaseFunPr(){ return  m_nPr;}
public :     int  m_nPb;
protected int  m_nPt;
private :    int  m_nPr;
};
class  Cpb: public  Base{
     //其他内容
public :
     int  GetPb(){ return  m_nPb;}
     int  GetPt(){ return  m_nPt;}
     int  GetPr(){ return  m_nPr;}
};
class  Cpt: protected  Base{
     //其他内容
public :
     int  GetPb(){ return  m_nPb;}
     int  GetPt(){ return  m_nPt;}
     int  GetPr(){ return  m_nPr;}
};
class  Cpr: private  Base{
     //其他内容
public :
     int  GetPb(){ return  m_nPb;}
     int  GetPt(){ return  m_nPt;}
     int  GetPr(){ return  m_nPr;}
};
   
int  main()
{
     Cpb objB;
     Cpt objT;
     Cpr objR;
     //其他内容
}

访问分为:类对象访问、类内访问两种;

对于基类继承下来的成员的访问与修改权限如下:

基类成员访问权限(列
public protected private
派生方式(行) 派生类对象 派生类类内 派生类对象
派生类类内
派生类对象
派生类类内
public 可访/可修 权限:public
可访/可修
可访/不可修 权限:protected
可访/不可修
可访/不可修 权限:private
可访/不可修
protected 可访/不可修 权限:protected
可访/可修
可访/不可修 权限:private
可访/可修
可访/不可修 权限:private
不可访/不可修
private 可访/不可修 权限:private
可访/可修
可访/不可修 权限:private
可访/可修
可访/不可修 权限:private
可访/不可修

派生类内不管是 public、protected、private 继承,总是可以访问基类中的public、protected 成员,基类中的 private 成员永远不能在派生类内直接访问,不论通过哪种方式。

派生类对象仅当public派生时,对基类中的public成员有可访问/可修改的权限,其他都为不可访问/不可修改。

用‘B’代表public,用'T‘代表protected,用'R’代表private;BT->T代表基类成员访问权限为B,派生方式为T,派生后成员在派生类内的访问权限为T;‘r'表示可访问,’w'代表可修改,‘-'表示不可访问或不可修改,在第一位表示不可访,在第二位表示不可修;则上表简化为如下:

 

访问权限变更
派生类对象 派生类类内 访问权限变更 派生类对象 派生类类内 访问权限变更
派生类对象 派生类类内
BB->B rw rw TB->T -- r- RB->R -- --
BT->T -- r- TT->R -- r- RT->R -- --
BR->R -- r- TR->R -- r- RR->R -- --

当派生类下面还有派生类时,派生类作为基类,权限更改同上!


#include <stdio.h>

// 单个类的访问控制
// public:    公有属性,  类的内部  外部 都能使用
// private:   私有属性, 类的内部可用, 外部不可用
// protected: 保护属性, 类的内部可用,外部不可用, 派生类的内部可用,主要继承
class Parent
{
public:
	int base_public;     // 名字

protected:
	int base_protect;    // 银行卡密码

private:
	int base_private;    // 情人
};

// private 私有继承:
// 父类的 public : 在派生类中还是 private, 类的内部可用、外部不能用
// 父类的 protect: 在派生类中还是 private,类的内部可用,外部不可用
// 父类的 private: 在派生类中还是 private, 但是 内部 、 外部 都不能用
class Child2: private Parent
{
public:
	void useValue()
	{
		base_public  = 10;
		base_protect = 20;
		// base_private = 30;  // err
	}
};

class Grandson2: public Child2
{
public:
	void useValue()
	{
		// base_public  = 10;  // err
		// base_protect = 20;  // err
		// base_private = 30;  // err
	}
};

// protected 保护继承:
// 父类的 public : 在派生类中还是 protect, 类的内部可用、外部不能用
// 父类的 protect: 在派生类中还是 protect,类的内部可用,外部不可用
// 父类的 private: 在派生类中还是 private, 但是 内部 、 外部 都不能用
class Child1: protected Parent
{
public:
	void useValue()
	{
		base_public  = 10;
		base_protect = 20;
		// base_private = 30;  // err
	}
};

class Grandson1:public Child1
{
public:
	void useValue()
	{
		base_public  = 10;
		base_protect = 20;
		// base_private = 30;
	}
};
// public 公有继承:
// 父类的 public : 在派生类中还是 public , 类的内部、外部都能访问
// 父类的 protect: 在派生类中还是 protect,类的内部可用,外部不可用
// 父类的 private: 在派生类中还是 private, 但是 内部 、 外部 都不能用
class Child : public Parent
{
public:
	void useValue()
	{
		base_public  = 10;   // ok
		base_protect = 20;   // ok
		// base_private = 30;   // err
	}
};


// 如何判断能访问还是不能访问
// 1、看在类的内部、外部
// 2、继承方式
// 3、在基类中的 原有权限
int main2_1()
{
	Parent p1;
	p1.base_public;
	// p1.base_protect;
	// p1.base_private;

	Child c1;
	c1.base_public = 10;  
	// c1.base_protect = 20;
	// c1.base_private = 30;

	Child1 c2;
	// c2.base_public = 10;  // err

	return 0;
}


判断能否被访问方法:

    1)看调用语句位置,这句话写在子类的内部、外部
    2)看子类如何从父类继承(public、private、protected)    
    3)看父类中的访问级别(public、private、protected)


继承权限:

不同的继承方式会影响基类成员在派生类中的访问权限。 

1) public继承方式基类中所有 public 成员在派生类中为 public 属性;基类中所有 protected 成员在派生类中为 protected 属性;基类中所有 private 成员在派生类中不能使用。

 2) protected继承方式基类中的所有 public 成员在派生类中为 protected 属性;基类中的所有 protected 成员在派生类中为 protected 属性;基类中的所有 private 成员在派生类中不能使用。 

3) private继承方式基类中的所有 public 成员在派生类中均为 private 属性;基类中的所有 protected 成员在派生类中均为 private 属性;基类中的所有 private 成员在派生类中不能使用。 

通过上面的分析可以发现:

1) 基类成员在派生类中的访问权限不得高于继承方式中指定的权限。例如,当继承方式为 protected 时,那么基类成员在派生类中的访问权限最高也为 protected,高于 protected 的会降级为 protected,但低于 protected 不会升级。再如,当继承方式为 public 时,那么基类成员在派生类中的访问权限将保持不变。 也就是说,继承方式中的 public、protected、private 是用来指明基类成员在派生类中的最高访问权限的。

 2) 不管继承方式如何,基类中的 private 成员在派生类中始终不能使用(不能在派生类的成员函数中访问或调用)。 

3) 如果希望基类的成员能够被派生类继承并且毫无障碍地使用,那么这些成员只能声明为 public 或 protected;只有那些不希望在派生类中使用的成员才声明为 private。

 4) 如果希望基类的成员既不向外暴露(不能通过对象访问),还能在派生类中使用,那么只能声明为 protected。 注意,我们这里说的是基类的 private 成员不能在派生类中使用,并没有说基类的 private 成员不能被继承。实际上,基类的 private 成员是能够被继承的,并且(成员变量)会占用派生类对象的内存,它只是在派生类中不可见,导致无法使用罢了。private 成员的这种特性,能够很好的对派生类隐藏基类的实现,以体现面向对象的封装性。      
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值