之前一直知道protected是介于private和public两种访问权限的中间者,影响友元和派生类的访问权限。但是对于具体的细节还有一些疑惑的地方,今天仔细研究了一下c++primer上关于这一部分的解释,简单做个总结如下。
首先我们只考虑派生列表中使用的访问说明符,即所谓的派生访问说明符。对于基类B中的不管是public,private还是protected成员,我们有以下的原则。
1.如果派生类D以public方式继承基类B,则D的成员可以访问B中的public和protected成员,而无法访问B的private成员。完成继承之后,B中原来的public成员在D中的访问权限依然是public的,B中原来的protected成员在D中的访问权限依然是protected的,B中的private成员在D中依然是private的。
2.如果派生类D以protected方式继承基类B,则D的成员可以访问B中的public和protected成员,而无法访问B的private成员。完成继承之后,B中原来的public成员在D中的访问权限变为protected的,B中的原来的protected成员在D中的访问权限依然是protected的,B中的private成员在D中依然是private的。
3.如果派生类D以private方式继承基类B,则D的成员可以访问B中的public和protected成员,而无法访问B的private成员。完成继承之后,B中原来的public成员和protected成员在D中的访问权限变为private的,B中的private成员在D中依然是private的。
由以上的三条原则可以知道,所谓的派生访问说明符,并不会影响D的成员对B的成员的访问权限,因为这个权限已经由B中成员的访问说明符全权规定。试想,假设我们通过指定派生访问说明符,就可以通过派生类D来访问基类B中本不对外界开放的成员(特指private成员),那么基类中的访问说明权限还有什么意义呢?
进一步思考我们可以得出,派生访问说明符其实定义的是,在派生类将基类的成员继承过来之后,这些成员在D中的新的访问权限。具体地说就是,如果以public来继承B,则B中成员的访问权限在D中具有相同的访问权限;如果以protected来继承B,则D中成员的访问权限的变化是public成员改变成protected成员,其余不变;如果以private来继承B,则D中的所有成员都变成了private成员。如果按照成员在基类B中的访问权限来划分的话,private成员不管怎么被继承,依然是private的;protected在private继承下,会变成private成员;而public成员在protected继承下会变成protected成员,在private继承下会变成private成员。
然而有的时候我们想改变某些对象在派生类中的访问权限应该怎么办呢?比如某个成员在基类中是public或者protected的,我们通过private继承之后它们必然会具有private的访问权限,如果想让它们具有非private的权限可以吗?这可以通过using关键字来实现。比如下面的例子。
class B{
public:
std::size_t size() const{return n;}
protected:
sdt::size_t n;
};
class D:private B{
public:
using B::size;
protected:
using B::n;
}
我们通过using关键字,手动的指定了从基类继承来的成员的访问权限。
当然,protected访问说明符同时还影响友元对其的访问,因为这个比较简单,我们在这里就不讨论了。只需要注意一点就是,友元不具有反身性,当然更不具有传递性。我们只能对每一对具有友元关系的目标进行明确指定。
以上是我对访问说明符的一些理解,写的比较啰嗦,但是个人感觉可以解释初学者大部分的疑惑了。欢迎大家指正批评。