单个类的访问权限
- public 修饰的成员变量 方法 在类的内部 类的外部都能使用
- protected: 修饰的成员变量方法,在类的内部使用 ,在继承的子类中可用 ;其他 类的外部不能被使用
- private: 修饰的成员变量方法 只能在类的内部使用 不能在类的外部
继承权限
不同的继承方式会影响基类成员在派生类中的访问权限。
1) public继承方式
- 基类中所有 public 成员在派生类中为 public 属性;
- 基类中所有 protected 成员在派生类中为 protected属性;
- 基类中所有 private 成员在派生类中不能使用。
2) protected继承方式
- 基类中的所有 public 成员在派生类中为 protected 属性;
- 基类中的所有 protected 成员在派生类中为protected 属性;
- 基类中的所有 private 成员在派生类中不能使用。
3) private继承方式
- 基类中的所有 public 成员在派生类中均为 private 属性;
- 基类中的所有 protected 成员在派生类中均为
- private 属性; 基类中的所有 private 成员在派生类中不能使用。
通过上面的分析可以发现:
基类成员在派生类中的访问权限不得高于继承方式中指定的权限。例如,当继承方式为 protected 时,那么基类成员在派生类中的访问权限最高也为 protected,高于 protected 的会降级为 protected,但低于protected 不会升级。再如,当继承方式为 public 时,那么基类成员在派生类中的访问权限将保持不变。
也就是说,继承方式中的 public、protected、private 是用来指明基类成员在派生类中的最高访问权限的。
不管继承方式如何,基类中的 private 成员在派生类中始终不能使用(不能在派生类的成员函数中访问或调用)。
如果希望基类的成员能够被派生类继承并且毫无障碍地使用,那么这些成员只能声明为 public 或 protected;只有那些不希望在派生类中使用的成员才声明为 private。
- 如果希望基类的成员既不向外暴露(不能通过对象访问),还能在派生类中使用,那么只能声明为 protected。
注意,我们这里说的是基类的 private 成员不能在派生类中使用,并没有说基类的 private 成员不能被继承。实际上,基类的 private 成员是能够被继承的,并且(成员变量)会占用派生类对象的内存,它只是在派生类中不可见,导致无法使用罢了。private 成员的这种特性,能够很好的对派生类隐藏基类的实现,以体现面向对象的封装性。
判断能否被访问方法
- 看调用语句位置,这句话写在子类的内部、外部
- 看子类如何从父类继承(public、private、protected)
- 看父类中的访问级别(public、private、protected)
#include <iostream>
using namespace std;
// 基类
class Parent
{
public:
int base_public; // 父亲的 名字
protected:
int base_protected; // 父亲的 银行卡密码
private:
int base_private; // 情人
};
// public > protected > private
// 继承 基类的权限 * 继承的权限 == 两个中最小的一个
// 派生类
// public : 公有继承
// 基类 public 成员:在派生类中还是 public 属性,在派生类的内部和外部都可以访问
// 基类 protected 成员:在派生类中还是 protected 属性,在派生类的内部可以访问, 外部不可以访问
// 基类 private 成员:在派生类中还是 private 属性,在派生类的内部和外部都不可以访问
class Child1 : public Parent // 亲儿子
{
public:
void setValue()
{
base_public = 3; // ok
base_protected = 4; // ok
// 1、base_private 是否类自己的内部成员
// 2、看在基类中的 访问权限
// base_private = 5; // err
}
};
// protected: 保护继承
// 基类 public 成员:在派生类中还是 protected 属性,在派生类的内部可以访问, 外部不可以访问
// 基类 protected 成员:在派生类中还是 protected 属性,在派生类的内部可以访问, 外部不可以访问
// 基类 private 成员:在派生类中还是 private 属性,在派生类的内部和外部都不可以访问
class Child2 : protected Parent // 私生子
{
void setValue()
{
base_public = 3; // ok
base_protected = 4; // ok
// 1、base_private 是否类自己的内部成员
// 2、看在基类中的 访问权限
// base_private = 5; // err
}
};
class GrandSon2: public Child2
{
void setValue()
{
base_public = 3; // base_public 在 Child2 中 protected 属性 所以可以访问
base_protected = 4; // base_protected 在 Child2 中 protected 属性 所以可以访问
// 1、base_private 是否类自己的内部成员
// 2、看在基类中的 访问权限
// base_private = 5; // err
}
};
// private: 私有继承
// 基类 public 成员:在派生类中还是 private 属性,在派生类的内部可以访问, 外部不可以访问
// 基类 protected 成员:在派生类中还是 private 属性,在派生类的内部可以访问, 外部不可以访问
// 基类 private 成员:在派生类中还是 private 属性,在派生类的内部和外部都不可以访问
class Child3:private Parent
{
void setValue()
{
base_public = 3; // ok
base_protected = 4; // ok
// 1、base_private 是否类自己的内部成员
// 2、看在基类中的 访问权限
// base_private = 5; // err
}
};
class GrandSon3:public Child3
{
public:
void setValue()
{
// base_public = 3; // base_public 在 Child3 中是 private 权限 所以不能访问
// base_protected = 4; // ok
}
};
int main()
{
Parent p;
// p.base_protected = 1;
Child1 c;
p.base_public = 1;
c.base_public = 2;
// c.base_protected = 2; // err
// c.base_private = 3; // err
Child2 c2;
// 1、base_public 是否是 Child2 的内部成员 不是
// 2、base_public 在基类中的权限 public
// 3、继承方式: protected
// c2.base_public = 1; // err
return 0;
}