成员的访问权限

public访问权限

一个类的public成员变量、成员函数,可以通过类的成员函数、类的实例变量进行访问

<实际上,类的成员函数,可以访问本类内的任何成员变量和成员函数>

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include<iostream>
#include<string>
using namespace std;
class AccessTest
{
public:
    int pub_mem;
    int pub_fun(){};
protected:
    int prot_mem;
    int prot_fun(){};
private:
    int priv_memb;
    int priv_fun(){};    
};
int main()
{
    AccessTest at;
    at.pub_mem;     //OK, 访问public成员变量
    at.pub_func();  //OK, 访问public成员函数
      return 0;
}

protected访问权限

一个类的protected成员变量、成员函数,无法通过类的实例变量进行访问。

但是可以通过类的友元函数、友元类和类的成员函数进行访问。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#include<string>
#include<iostream>
using namespace std;
class AccessTest
{
    friend void Atest();
    friend class CAtest;
    public:
        int pub_mem;
        void pub_fun(){}
    protected:
        int prot_mem;
        void prot_fun(){}
    private:
        int priv_memb;
        void priv_fun(){}

};

class CAtest
{
    public:
        void x()
        {
          AccessTest t;
          t.prot_fun();      //OK,友元类可以访问protected成员函数
          int x=t.prot_mem;  //OK,友元类可以访问protected成员变量
   }
};

void Atest()
{
    AccessTest t;
    t.prot_fun();     //OK,友元函数可以访问protected成员函数
    int x=t.prot_mem;  //OK,友元函数可以访问protected成员变量
}

int main()
{
    AccessTest at;
    at.prot_mem;      //ERROR,类实例变量无法访问protected成员变量
    at.prot_fun();    //ERROR,类实例变量无法访问protected成员函数
    Atest();
    return 0;
}

private访问权限

一个类的private成员变量、成员函数,无法通过类的实例变量进行访问。

但是可以通过类的友元函数、友元类和类内成员函数进行访问。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include<iostream>
#include<string>

using namespace std;

class AccessTest
{
friend void Atest();
friend class CAtest;
public:
    int pub_mem;
    void pub_fun(){}
protected:
    int prot_mem;
    void prot_fun(){}
private:
    int priv_memb;
    void priv_fun(){}

};

class CAtest
{
public:
void x()
{
       AccessTest t;
           t.priv_fun();       //OK,友元类可以访问private成员函数
       int x=t.priv_memb;  //OK,友元类可以访问private成员变量
    }
};

void Atest()
{
AccessTest t;
t.priv_fun();       //OK,友元函数可以访问private成员函数
int x=t.priv_memb;  //OK,友元函数可以访问private成员变量
}    

int main()
{
AccessTest at;
at.priv_memb;       //ERROR,类实例变量无法访问private成员变量
at.priv_fun();      //ERROR,类实例变量无法访问private成员函数
Atest();
    return 0;
}

总结

public在任何地方都能访问,protected只能在派生类中访问, private只能在友元中访问。

继承的访问权限控制

public继承

派生类通过public继承,基类的各种权限不变 。

派生类的成员函数,可以访问基类的public成员、protected成员,但是无法访问基类的private成员。

派生类的实例变量,可以访问基类的public成员,但是无法访问protected、private成员。

可以将public继承看成派生类将基类的public,protected成员囊括到派生类的public和protected中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include<iostream>
#include<string>

using namespace std;

class AccessTest
{
    public:
        int pub_mem;
        void pub_fun(){}
    protected:
        int prot_mem;
        void prot_fun(){}
    private:
        int priv_memb;
        void priv_fun(){}

};

class DAccessTest:public AccessTest
{
    public:
        void test()
        {
            int x=pub_mem; //OK
            pub_fun(); //OK

            int y=prot_mem;//OK
            prot_fun();//OK

            int z=priv_memb;   //ERROR
            priv_fun();//ERROR
        }

};
int main()
{
    DAccessTest dt;
    int x=dt.pub_mem;//OK
    int y=dt.prot_mem;   //ERROR
    int z=dt.priv_memb;  //ERROR
return 0;
}

protected继承

派生类通过protected继承,基类的public成员在派生类中的权限变成了protected,protected和private不变。

派生类的成员函数,可以访问基类的public成员、protected成员,但是无法访问基类的private成员。

派生类的实例变量,无法访问基类的任何成员,因为基类的public成员在派生类中变成了protected。

可以将protected继承看成派生类将基类的public,protected成员全部作为派生类的protected成员。

private成员是基类内部的隐私,除了基类的友元,所有不得窥探。派生类的友元,也不能访问

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include<iostream>
#include<string>
using namespace std;
class AccessTest
{
    friend void Atest();
    friend class CAtest;
    public:
        int pub_mem;
        void pub_fun(){}
    protected:
        int prot_mem;
        void prot_fun(){}
    private:
        int priv_memb;
        void priv_fun(){}

};
class DAccessTest:protected AccessTest
{
    public:
        void test()
        {
            int x=pub_mem;     //OK
            pub_fun();         //OK

            int y=prot_mem;    //OK
            prot_fun();        //OK

            int z=priv_memb;   //ERROR
            priv_fun();        //ERROR
        }

};
int main()
{
    DAccessTest dt;
    int x=dt.pub_mem;    //ERROR,基类的成员现在是派生类的保护成员
    int y=dt.prot_mem;   //ERROR,基类的成员现在是派生类的保护成员
    int z=dt.priv_memb;  //ERROR
  return 0;
}

private继承

派生类通过private继承,基类的public成员在派生类中的权限变成了private。

派生类的成员函数,可以访问基类的public成员、protected成员,但是无法访问基类的private成员。

派生类的实例变量,无法访问基类的任何成员,因为基类的所有成员在派生类中变成了private。

可以将private继承看成派生类将基类的public,protected成员囊括到派生类,全部作为派生类的private成员,但是不包括private成员。

private成员是基类内部的隐私,除了基类的友元,所有不得窥探。派生类的友元,都不能访问

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include<iostream>
#include<string>

using namespace std;

class AccessTest
{
    friend void Atest();
    friend class CAtest;
    public:
        int pub_mem;
        void pub_fun(){}
    protected:
        int prot_mem;
        void prot_fun(){}
    private:
        int priv_memb;
        void priv_fun(){}

};

class DAccessTest:private AccessTest
{
    public:
        void test()
        {
            int x=pub_mem; //OK
            pub_fun(); //OK

            int y=prot_mem;//OK
            prot_fun();//OK

            int z=priv_memb;   //ERROR
            priv_fun();//ERROR
        }

};



int main()
{
    DAccessTest dt;
    int x=dt.pub_mem;//ERROR,基类的成员现在是派生类的私有成员
    int y=dt.prot_mem;   //ERROR,基类的成员现在是派生类的私有成员
    int z=dt.priv_memb;  //ERROR, private成员无法访问
  return 0;
}

总结

继承修饰符,就像是一种筛子,将基类的成员筛到派生类。public、protected、private,就是筛子的眼。

通过public继承,所有基类成员(除了private),public、protected都到了派生类里面,public筛眼比较大,不会改变访问权限。

通过protected继承,所有基类成员(除了private),public、protected都到了派生类里面,protected筛眼大小适中,所有过来的成员都变成了protected。

通过private继承,所有基类成员(除了private),public、protected都到了派生类里面,private筛眼最小,所有过来的成员都变成了private。

class和struct的区别

class不写修饰符,成员默认是private的,而struct 默认是public的

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Base   //默认private
{
int a;
int b;
}

Base ba;
int x=ba.a;//错误
int y=ba.b;//错误

struct St  //默认public
{
int a;
int b;
}

St st;
int x=st.a; //OK
int y=st.b;//OK
class的继承默认是private的,而struct默认是public的

class Base{...};  
class Derive:Base{...}  //private继承  

struct BStruct{...};  
struct DStruct:BStruct{...};//public继承