C++中,存在三种访问控制修饰符,它们分别是:
为了使文章容易理解,我们首先对以下术语作出说明:
在以下的例子中,我们创建了一个简单的类。
下面,我们就来探究一下,对于该类中被不同访问控制修饰符修饰的成员,该类的对象都有什么样的访问权限。
#include <iostream>
using namespace std;
class CBase
{
private:
    int a_base_private;
protected:
    int b_base_protected;
public:
    int c_base_public;
    
public: 
    CBase(){a_base_private = 1; b_base_protected = 2; c_base_public = 3;}
    ~CBase(){}
    int getA() const {return a_base_private;}       // OK, 类可以访问自身的所有成员
    int getB() const {return b_base_protected;}     // OK, 类可以访问自身的所有成员
    int getC() const {return c_base_public;}        // OK, 类可以访问自身的所有成员
};
int main()
{
    int tmp;
    CBase baseObj;
    
    //baseObj.a_base_private = 1;           // KO, 对象不能访问类的private成员
    //baseObj.b_base_protected = 1;         // KO, 对象不能访问类的protected成员
    baseObj.c_base_public = 1;              // OK, 对象可以访问类的public成员
    
    tmp = baseObj.getA();       // OK, 对象可以访问类的public成员
    tmp = baseObj.getB();       // OK, 对象可以访问类的public成员
    tmp = baseObj.getC();       // OK, 对象可以访问类的public成员
}
从以上实践中可以得出以下结论:
在以上例子的基础上,让我们来考虑一下,对于该类中被不同访问控制修饰符修饰的成员,该类的友元函数和友元类对这些成员都有什么样的访问权限。
#include <iostream>
using namespace std;
class CBase;
class CFriend;
void ClearBaseA(CBase &obj);
class CBase
{
friend  CFriend;                            // 声明CFriend为自己的友元类
friend  void ClearBaseB(CBase &obj);        // 声明ClearBaseA为自己的友元函数
private:
    int a_base_private;
protected:
    int b_base_protected;
public:
    int c_base_public;
    
public: 
    CBase(){a_base_private = 1; b_base_protected = 2; c_base_public = 3;}
    ~CBase(){}
    int getA() const {return a_base_private;}       // OK, 类可以访问自身的所有成员
    int getB() const {return b_base_protected;}     // OK, 类可以访问自身的所有成员
    int getC() const {return c_base_public;}        // OK, 类可以访问自身的所有成员
};
class CFriend
{
private:
    CBase obj;
    
public:
    CFriend(){}
    ~CFriend(){}
    
    int setBaseA(int f) {obj.a_base_private = f;}       // OK, 在友元类中,可以访问Base类的私有成员
    int getBaseA() const {return obj.getA();}
};
void ClearBaseB(CBase &obj)
{
    obj.b_base_protected = 0;           // OK, 在友元函数中,可以访问Base类的保护成员
}
int main()
{
    int tmp;
    CBase baseObj;
    CFriend friendObj;
    
    cout << baseObj.getB() << endl;     // 通过构造函数初始化为2
    ClearBaseB(baseObj);
    cout << baseObj.getB() << endl;     // 被友元函数给清0了
    
    cout << friendObj.getBaseA() << endl;   // 通过构造函数初始化为1
    friendObj.setBaseA(7);
    cout << friendObj.getBaseA() << endl;   // 被友元类给设置为了7
}
由上例中可以看出,友元可以访问类中的private和protected成员,对于public成员,当然更是可以访问的了,虽然以上例子中并没有验证这一点。
所以,我们可以得出以下结论:
我们换一个角度,通过以下表格总结一下。
| 访问控制修饰符 | 类 | 对象 | 友元 | 
|---|---|---|---|
| public | 可访问 | 可访问 | 可访问 | 
| protected | 可访问 | 不可访问 | 可访问 | 
| private | 可访问 | 不可访问 | 可访问 | 
在C++中,在继承的过程中,有以下三种继承方式,它们分别是:
在第一个例子的基础之上,我们通过public方式继承出一个新的派生类。
#include <iostream>
using namespace std;
class CBase
{
private:
    int a_base_private;
protected:
    int b_base_protected;
public:
    int c_base_public;
    
public: 
    CBase(){a_base_private = 1; b_base_protected = 2; c_base_public = 3;}
    ~CBase(){}
    int getA() const {return a_base_private;}       // OK, 类可以访问自身的所有成员
    int getB() const {return b_base_protected;}     // OK, 类可以访问自身的所有成员
    int getC() const {return c_base_public;}        // OK, 类可以访问自身的所有成员
};
class CDerived:public CBase
{
private:
    int x_derived_private;
protected:
    int y_derived_protected;
public:
    int z_derived_private;
    
public:
    CDerived(){x_derived_private = 4; y_derived_protected = 5; z_derived_private = 6;}
    ~CDerived(){}
    
    //void setBaseA(int t){a_base_private = t;}     // KO, 派生类中不能访问基类的private成员
    void setBaseB(int t){b_base_protected = t;}     // OK, 派生类中可以访问基类的protected成员
    void setBaseC(int t){c_base_public = t;}        // OK, 派生类中可以访问基类的public成员  
    int getX() const {return x_derived_private;}
    int getY() const {return y_derived_protected;}
    int getZ() const {return z_derived_private;}
};
int main()
{
    CDerived derivedObj;
    
    //derivedObj.a_base_private = 1;            // KO, 基类中由private修饰的a_base_private,对派生类是不可见的,即使在派生类中都不能访问,更别提派生类对象了。 
    //derivedObj.b_base_protected = 1;          // KO, 对象不能访问类的protected成员(public方式继承的protected成员,在派生类中仍为protected成员)
    derivedObj.c_base_public = 1;               // OK, 对象可以访问类的public成员(public方式继承的public成员,在派生类中仍为public成员)
    
    cout << derivedObj.getA() << endl;      // OK, 对象可以访问类的public成员(public方式继承的public成员,在派生类中仍为public成员)
    derivedObj.setBaseB(8);                 // OK, 对象可以访问类的public成员
    cout << derivedObj.getB() << endl;      // OK, 对象可以访问类的public成员(public方式继承的public成员,在派生类中仍为public成员)
    derivedObj.setBaseC(9);                 // OK, 对象可以访问类的public成员
    cout << derivedObj.getC() << endl;      // OK, 对象可以访问类的public成员(public方式继承的public成员,在派生类中仍为public成员)
}
由以上例子可以看出:
在第一个例子的基础之上,我们通过protected方式继承出一个新的派生类。
#include <iostream>
using namespace std;
class CBase
{
private:
    int a_base_private;
protected:
    int b_base_protected;
public:
    int c_base_public;
    
public: 
    CBase(){a_base_private = 1; b_base_protected = 2; c_base_public = 3;}
    ~CBase(){}
    int getA() const {return a_base_private;}       // OK, 类可以访问自身的所有成员
    int getB() const {return b_base_protected;}     // OK, 类可以访问自身的所有成员
    int getC() const {return c_base_public;}        // OK, 类可以访问自身的所有成员
};
class CDerived:protected CBase
{
private:
    int x_derived_private;
protected:
    int y_derived_protected;
public:
    int z_derived_private;
    
public:
    CDerived(){x_derived_private = 4; y_derived_protected = 5; z_derived_private = 6;}
    ~CDerived(){}
    //void setBaseA(int t){a_base_private = t;}     // KO, 派生类中不能访问基类的private成员
    void setBaseB(int t){b_base_protected = t;}     // OK, 派生类中可以访问基类的protected成员
    void setBaseC(int t){c_base_public = t;}        // OK, 派生类中可以访问基类的public成员
    int getX() const {return x_derived_private;}    // OK, 类可以访问自身的所有成员
    int getY() const {return y_derived_protected;}  // OK, 类可以访问自身的所有成员
    int getZ() const {return z_derived_private;}    // OK, 类可以访问自身的所有成员
};
int main()
{
    CDerived derivedObj;
    
    //derivedObj.a_base_private = 1;            // KO, 对象不能访问类的private成员(protected方式继承的private成员,在派生类中不可见)
    //derivedObj.b_base_protected = 1;          // KO, 对象不能访问类的protected成员(protected方式继承的protected成员,在派生类中仍为protected成员)
    //derivedObj.c_base_public = 1;             // KO, 对象不可以访问类的protected成员(protected方式继承的public成员,在派生类中成为protected成员)
    
    //cout << derivedObj.getA() << endl;        // KO, 对象不可以访问类的protected成员(protected方式继承的public成员,在派生类中成为protected成员)
    //cout << derivedObj.getB() << endl;        // KO, 对象不可以访问类的protected成员(protected方式继承的public成员,在派生类中成为protected成员)
    //cout << derivedObj.getC() << endl;        // KO, 对象不可以访问类的protected成员(protected方式继承的public成员,在派生类中成为protected成员)
}
由以上例子可以看出:
在第一个例子的基础之上,我们通过private方式继承出一个新的派生类。
#include <iostream>
using namespace std;
class CBase
{
private:
    int a_base_private;
protected:
    int b_base_protected;
public:
    int c_base_public;
    
public: 
    CBase(){a_base_private = 1; b_base_protected = 2; c_base_public = 3;}
    ~CBase(){}
    int getA() const {return a_base_private;}       // OK, 类可以访问自身的所有成员
    int getB() const {return b_base_protected;}     // OK, 类可以访问自身的所有成员
    int getC() const {return c_base_public;}        // OK, 类可以访问自身的所有成员
};
class CDerived:private CBase
{
private:
    int x_derived_private;
protected:
    int y_derived_protected;
public:
    int z_derived_private;
    
public:
    CDerived(){x_derived_private = 4; y_derived_protected = 5; z_derived_private = 6;}
    ~CDerived(){}
    //void setBaseA(int t){a_base_private = t;}     // KO, 派生类中不能访问基类的private成员,因为其在派生类中不可见
    void setBaseB(int t){b_base_protected = t;}     // OK, 派生类中可以访问基类的protected成员
    void setBaseC(int t){c_base_public = t;}        // OK, 派生类中可以访问基类的public成员
    int getX() const {return x_derived_private;}    // OK, 类可以访问自身的所有成员
    int getY() const {return y_derived_protected;}  // OK, 类可以访问自身的所有成员
    int getZ() const {return z_derived_private;}    // OK, 类可以访问自身的所有成员
};
int main()
{
    CDerived derivedObj;
    
    //derivedObj.a_base_private = 1;            // KO, (private方式继承的private成员,在派生类中不可见)
    //derivedObj.b_base_protected = 1;          // KO, (private方式继承的protected成员,在派生类中不可见)
    //derivedObj.c_base_public = 1;             // KO, (private方式继承的public成员,在派生类中成为不可见)
    
    //cout << derivedObj.getA() << endl;        // KO, (private方式继承的public成员,在派生类中不可见)
    //cout << derivedObj.getB() << endl;        // KO, (private方式继承的public成员,在派生类中不可见)
    //cout << derivedObj.getC() << endl;        // KO, (private方式继承的public成员,在派生类中不可见)
    
    cout << derivedObj.getX() << endl;
    cout << derivedObj.getY() << endl;
    cout << derivedObj.getZ() << endl;
}
由以上例子可以看出:
| 访问控制修饰符 | public继承 | protected继承 | private继承 | 
|---|---|---|---|
| public | public | protected | private | 
| protected | protected | protected | private | 
| private | private | private | private | 
原文:https://www.cnblogs.com/outs/p/10128993.html