C++第十五章:抽象基类--访问控制与继承--友员关系与继承

抽象基类

含有(或者未经覆盖直接继承)纯虚函数的类是抽象基类,抽象基类不能构建对象也就是没有对象

纯虚函数直接将继承来的虚函数后书写 =0
例如
double net_price(size_t)const = 0;

访问控制与继承

1.gongyprotected成员

首先一个类使用protected关键字来声明那些希望与派生类分享
但是不想被其他公共访问使用的成员,有3个特征
1.和私有成员类似,受protected的成员对于
  类的用户(这个用户应该是指类的具体对象)来说是不可访问的
  自己类自身的成员可以访问
2.和公有成员类似,基类受protected的成员被派生类继承,
  则派生类的成员和友员是可以访问的
3.派生类的成员或友元只能通过派生类的对象来访问基类(指的派生类基类部分)
  的受保护成员
针对第3点 看以下示例:
 class CSL
{
public:
	void print()
	{
		cout << protected_s << endl;

	};
protected:
	string protected_s= "ssss" ;
};
class CSL_der :public CSL
{   
public:
//派生类的成员或友元只能通过派生类的对象来
//访问基类(指的派生类基类部分),但这里派生类访问没有经过派生类的对象来访问
//是错的吗?,并不是,其实是(*this).protected_s这样调用的,这个对象就是*this
//也就是CSL_der派生类的对象csl_dercsl
	void print1()
	{
cout << protected_s << endl;
	}

};
CSL_der csl_dercsl;
csl_dercsl.print1();//从这里调用rint1() 其实传递了this这个额外的隐式参数

2.公有私有和受保护的继承

第一种情况:派生类中的其他成员(也就是派生类中的成员及友员):

啊
由上面的代码片段可以看出,无论派生访问说明符(即继承的方式)是public还private,对于派生类中的其他成员(也就是派生类中的成员及友员)派生类直接基类部分中的成员的访问权限并没有发生改变。由上面的例子可以得出结论:派生访问说明符对于派生类的成员(及友元)能否访问其直接基类的成员没什么影响。对基类成员的访问权限只与基类中的访问说明符有关。Pub_Derv和Priv_Derv都能访问受保护的成员prot_mem,同时它们都不能访问私有成员priv_mem。接着上面已有的代码来再看一个例子:

///
第二种情况:派生类构造的对象:在这里插入图片描述
由上面的代码片段可以看出,对于派生类构造的对象,在这里可以看出派生访问说明符起了作用,因为原本基类中公有的成员由于私有继承而使得派生类的对象(用户)无法访问。由此可以得出结论:派生访问说明符的目的是控制派生类对象(用户)(包括派生类的派生类在内)对于基类成员的访问权限。Pub_Derv和Priv_Derv都继承了pub_mem函数。如果继承是公有的,则成员将遵顼其原有的访问说明符,此时d1可以调用pub_mem。在Priv_Derv中,Base成员是私有的因此类的对象(用户)不能调用pub_mem,因为在这个派生类中基类部分是private


第三种情况:包括派生类的派生类:

在上面的第二种情况结论中还提到了一种用户,派生类的派生类称作第三种访问类成员的用户——继承自派生类的新类。在访问权限的角度上看,这种用户和第二种情况(用户的对象)的权限是一致的,这里的权限一致指的是得到的成员的访问权限,它们都受两个位置说明符的共同作用,下面的例子说明了这一点:
在这里插入图片描述
Pub_Derv的派生类之所以能访问Base的prot_mem成员是因为该成员Pub_Derv中仍然是受保护的,public继承过来仍然是受保护的,那这时Derived-from_public类中的其他成员(也就是派生类中的成员及友员)仍然可以访问。相反,Priv_Derv的派生类无法执行prot_mem的访问,因为对于类Derved_from_private来说,在类的基类部分prot_mem是私有的了,所以对于它们来说,类Derved_from_private的基类部分prot_mem也是私有的了

友员关系与继承

//c++Primer 中给出的例子
class base{
    friend class Frand;
protected :
    int i;
};
 
//Frand has no access to members in D1
class D1:public Base{
protected:
     int j;
};
class Frand{
public:
     int mem(Base b){return b.i;}  //ok,Frand is friend to Base
     int mem(D1 d){return d.i;}   //error,friendship doesn't inherit
}
 
//D2 has no aeecss to members in Base
class D2:public Frand{
public:
     int mem(Base b){return b.i;}  // error,friendship doesn't inherit
};

D1是base的派生类,Frand是base的友元类,D2是Frand的派生类,
Frand中:
int mem(Base b){return b.i;}  //正确:Frand是base的友元类所以可以访问Base的保护和私有
int mem(D1 d){return d.i;}   //错误:D1是base的派生类,派生类不能访问基类的保护或私有,
                             //且只能访问自己基类部分的保护,再者体现基类中的友元关系不继承
                             //如果可以继承,则Frand也是D1的友元类了,则应该可以访问了
D2中:
int mem(Base b){return b.i;}  //错误: 尽管Frand是base的友元类,D2是Frand的派生类,
                            //但友元关系不继承,所以D2不是base的友元类。所以不能访问base的保护和私有 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值