六一的部落格


关关难过关关过,前路漫漫亦灿灿。



派生访问属性用于类的继承; 成员访问说明符protected用于类的继承

访问说明符 access specifiers


关键字class和struct的区别

默认的成员访问属性和派生访问属性不同

关键字 默认的成员访问属性 默认的派生访问属性
class private private
struct public public

以class为例:

使用class定义类时, 未给出成员访问说明符, 类成员的默认访问属性为private;

使用class定义类时, 未给出派生访问属性, 默认以private的方式派生基类


成员访问说明符

成员访问说明符 类用户是否可以访问该成员 类的成员函数和友元是否可以访问该成员
public O O
pivate和protected X O
  1. 类的用户为程序员, 通过类对象访问类的公有成员

  2. 类的成员函数也许是供类的用户使用, 也许是供类的设计者使用; 类的成员函数对其他成员的访问, 常被描述为类的内部对其他成员进行访问

  3. 类的友元亦是提供给类的用户使用的接口

    之所以未定义为类的公有成员, 注意到, 通过类对象访问类的公有成员, 即以该类对象作为媒介

    通常将一些运算符重载定义为类的友元, 而这类运算符的操作数并不以某类对象为主


派生访问说明符

修改了基类成员在派生类中的访问属性, 用以控制派生类用户是否可以使用基类成员

基类各种访问属性成员在派生类中的访问属性:

基类成员的访问属性 派生访问属性为public时, 在派生类的成员访问属性 派生访问属性为protected时, 在派生类的成员访问属性 派生访问属性为private时, 在派生类的成员访问属性
public public protected private
protected protected protected private
private private, 派生类不可访问 private, 派生类不可访问 private, 派生类不可访问

基类的private成员, 派生类不可访问

基类的非私有成员, 派生类可以访问

派生访问属性, 一则决定了派生类用户对基类公有成员的访问权限, 二则决定了间接派生类对基类成员的访问权限

派生类直接继承基类, 间接派生类直接继承派生类, 间接继承基类

  1. 不影响直接派生类的内部和友元对基类public和protected成员的访问

    如果派生访问说明符为private, 直接派生类的内部和友元仍可访问基类public和protected成员, 间接派生类的内部和友元无法访问基类的所有成员

    • B派生自A, 派生访问属性为private: B无法访问a, 但可以调用printA

    • C派生自B, 派生访问属性为public; A亦是C的基类: C无法访问b, 但可以调用printB; C无法访问a, 也无法调用printA

     1class A
     2{
     3    int a = 0;
     4
     5protected:
     6    void printA();
     7};
     8
     9class B : A {
    10    int b = 1;
    11
    12protected:
    13    void printB();
    14};
    15
    16class C : public B {
    17    // ...
    18};
  2. 控制派生类的用户对基类public成员的访问

    如果派生类访问说明符不为public, 派生类用户无法访问基类的public成员

    • 类B的用户可以访问其公有成员, 即调用printB

    • B派生自A, 派生访问属性为protected: B的用户无法访问A的公有成员, 即无法调用printA

     1class A
     2{
     3    int a = 0;
     4public:
     5    void printA();
     6};
     7
     8class B: protected A
     9{
    10    int b = 1;
    11
    12public:
    13    void printB();
    14};
    15
    16B b;
    17b.printB();
  3. 控制间接派生类的内部和友元对基类public和protected成员的访问

    • 类B派生自A, 派生访问属性为private: B的内部和友元仍可访问A的非私有成员

    • 类C派生自B, 派生访问属性为public: C的内部和友元不可访问A的所有成员

     1class A
     2{
     3    int a = 0;
     4
     5protected:
     6    void printA();    
     7};
     8
     9class B: A
    10{
    11    friend void printAB(const B &b);
    12
    13    int b = 1;
    14
    15protected:
    16    void printB();    
    17};
    18
    19void printAB(const B &b) { b.printA(); b.printB(); }
    20
    21class C: public B
    22{
    23    friend void printBC(const C &c);
    24
    25    int c = 3;
    26
    27protected:
    28    void printC();    
    29};
    30
    31void printBC(const C &c) { c.printB(); c.printC(); }
    32
    33C c;
    34printBC(c);

派生类的成员函数和友元, 只能通过派生类对象访问其基类部分, 不能通过基类对象访问基类成员


成员的访问权限


派生访问属性用于类的继承; 成员访问说明符protected用于类的继承

访问说明符 access specifiers


关键字class和struct的区别

默认的成员访问属性和派生访问属性不同

关键字 默认的成员访问属性 默认的派生访问属性
class private private
struct public public

以class为例:

使用class定义类时, 未给出成员访问说明符, 类成员的默认访问属性为private;

使用class定义类时, 未给出派生访问属性, 默认以private的方式派生基类


成员访问说明符

成员访问说明符 类用户是否可以访问该成员 类的成员函数和友元是否可以访问该成员
public O O
pivate和protected X O
  1. 类的用户为程序员, 通过类对象访问类的公有成员

  2. 类的成员函数也许是供类的用户使用, 也许是供类的设计者使用; 类的成员函数对其他成员的访问, 常被描述为类的内部对其他成员进行访问

  3. 类的友元亦是提供给类的用户使用的接口

    之所以未定义为类的公有成员, 注意到, 通过类对象访问类的公有成员, 即以该类对象作为媒介

    通常将一些运算符重载定义为类的友元, 而这类运算符的操作数并不以某类对象为主


派生访问说明符

修改了基类成员在派生类中的访问属性, 用以控制派生类用户是否可以使用基类成员

基类各种访问属性成员在派生类中的访问属性:

基类成员的访问属性 派生访问属性为public时, 在派生类的成员访问属性 派生访问属性为protected时, 在派生类的成员访问属性 派生访问属性为private时, 在派生类的成员访问属性
public public protected private
protected protected protected private
private private, 派生类不可访问 private, 派生类不可访问 private, 派生类不可访问

基类的private成员, 派生类不可访问

基类的非私有成员, 派生类可以访问

派生访问属性, 一则决定了派生类用户对基类公有成员的访问权限, 二则决定了间接派生类对基类成员的访问权限

派生类直接继承基类, 间接派生类直接继承派生类, 间接继承基类

  1. 不影响直接派生类的内部和友元对基类public和protected成员的访问

    如果派生访问说明符为private, 直接派生类的内部和友元仍可访问基类public和protected成员, 间接派生类的内部和友元无法访问基类的所有成员

    • B派生自A, 派生访问属性为private: B无法访问a, 但可以调用printA

    • C派生自B, 派生访问属性为public; A亦是C的基类: C无法访问b, 但可以调用printB; C无法访问a, 也无法调用printA

     1class A
     2{
     3    int a = 0;
     4
     5protected:
     6    void printA();
     7};
     8
     9class B : A {
    10    int b = 1;
    11
    12protected:
    13    void printB();
    14};
    15
    16class C : public B {
    17    // ...
    18};
  2. 控制派生类的用户对基类public成员的访问

    如果派生类访问说明符不为public, 派生类用户无法访问基类的public成员

    • 类B的用户可以访问其公有成员, 即调用printB

    • B派生自A, 派生访问属性为protected: B的用户无法访问A的公有成员, 即无法调用printA

     1class A
     2{
     3    int a = 0;
     4public:
     5    void printA();
     6};
     7
     8class B: protected A
     9{
    10    int b = 1;
    11
    12public:
    13    void printB();
    14};
    15
    16B b;
    17b.printB();
  3. 控制间接派生类的内部和友元对基类public和protected成员的访问

    • 类B派生自A, 派生访问属性为private: B的内部和友元仍可访问A的非私有成员

    • 类C派生自B, 派生访问属性为public: C的内部和友元不可访问A的所有成员

     1class A
     2{
     3    int a = 0;
     4
     5protected:
     6    void printA();    
     7};
     8
     9class B: A
    10{
    11    friend void printAB(const B &b);
    12
    13    int b = 1;
    14
    15protected:
    16    void printB();    
    17};
    18
    19void printAB(const B &b) { b.printA(); b.printB(); }
    20
    21class C: public B
    22{
    23    friend void printBC(const C &c);
    24
    25    int c = 3;
    26
    27protected:
    28    void printC();    
    29};
    30
    31void printBC(const C &c) { c.printB(); c.printC(); }
    32
    33C c;
    34printBC(c);

派生类的成员函数和友元, 只能通过派生类对象访问其基类部分, 不能通过基类对象访问基类成员