要点

直接看代码:

class A {
public:
    int pub_a;
    void pub_fun();
private:
    //private成员 派生类不能访问,使用者不能使用
    int pri_a;
    void pri_fun();
protected:
    //protected成员 变成派生类的private成员 对类使用者是private,不可访问
    void pro_fun();
    int pro_a;
};


class ProA;
//Public继承不改变任何基类的访问属性.原来pub还是pub,原来protected还是protected.
struct PubA : public A {
    void func()
    {
        pub_fun();
        pub_a = 100;
        pro_fun();
        pro_a = 100;
        //pri_a  =100;
        //pri_fun();
    }
    void func(A & a)
    {
        a.pub_a = 10;
        //类成员为基类时时,仍然遵循"类使用者"的原则.即它只能访问pub成员
        //a.pro_a =10;
    }
    void func(PubA & pa)
    {
        //类成员为自身or成员函数的使用的类为自身时,就像是"自己的成员一样", 可以访问pub和protected成员
        pa.pub_a = 100;
        //Amazing here
        pa.pro_a  = 100;
        pro_a = 100;
    }
};


//Privte继承 将所有父类的属性修改为private
struct PriA : private A {
    void func()
    {
        pub_fun();
        pub_a = 100;
        pro_fun();
        pro_a = 100;
        //pri_a  =100;
        //pri_fun();
    }
};


struct ChildOfPriA : public PriA {
    void fun()
    {
        //都不能用
        //pub_a =100;
        //pub_fun();
    }
};

//Protect继承 里把基类的public属性变成自己的protected属性
struct ProA : protected A {
    void func()
       {
        pub_a = 100;
        pro_a = 100;
        //pri_a = 100;
}
};

struct B: private ProA {
public:
    //using 可以覆盖访问属性的继承关系
    //本来private继承过来的所有变量都是private.
    //但是using 一声明,意味着将它的访问属性改成public
    //注意作用域符号用了2层
    using PubA::A::pub_a;

    void fun(PubA & puba, ProA & proa, PriA & pria, A & a)
    {
        a.pub_a = 100;
        puba.pub_a = 100;

    }
};

struct C : public  A {
    //这里定义的变量隐藏了基类A中的pub_a
    int pub_a;
    void func()
    {
        //加上作用域符号显示使用基类被隐藏的变量
        auto ret = pub_a + A::pub_a;
        ret  += 100;
    }
};

int main()
{

    ProA a;
    //pub_a变成了ProA的protected变量,类使用者不能访问.
    //a.pub_a = 100;
    PubA puba;

    puba.pub_a = 100;
    //类使用者不能访问protected
    //b.pro_a = 100;
    //
    B b;
    b.pub_a = 100;

    return 0;
}