public protected private关键字权限

public protected private关键字

我们知道C++中的类,有三种访问权限(也称作访问控制),它们分别是public、protected、private。

关于这三个关键字理解了下面的框图

访问权限 public protected private
对本类 可见 可见 可见
对子类 可见 可见 不可见
对外部(调用) 可见 不可见 不可见

框图第一行看(对本类行),则代表着类内部三个关键字的权限。
如果框图一列列看,则代表继承角度来看三个关键字的权限。如public列代表对本类,对子类,对外部调用三种情况的权限,其它列相同。

代码验证上表框图权限关系

#include <iostream>
#include <string>
#include <string.h>
#include <thread>

using namespace std;

namespace zj001{
    
    

class Person{
    
    
    public:
        Person(const string& name, int age ):m_name(name), m_age(age){
    
    }
        void showPersonNameInfo() const {
    
     cout << "Person name:" << m_name << endl; }
    protected:
        void showPersonAgeInfo() const {
    
     cout << "Person age:" << m_age << endl; }
        bool setPersonAge(int age) {
    
     m_age = age; return true;}
        int v_age;
    private:
        string m_name;
        int m_age;
};

class Teacher: public Person {
    
    
    public:
        Teacher(const string name, int age, const string title):
        Person(name, age), m_title(title){
    
    }

        void showTeacherTitleInfo() const {
    
     cout << "Tech title: " << m_title << endl;  }
        bool setTeacherVirtualAge(int age) {
    
     v_age = age; return true; } // Ok base protected call 
    protected:
        void showTeacherAgeInfo() const {
    
     showPersonAgeInfo(); } //Ok base protected call
        //bool setTeacherAge(int age) { m_age = age; return true; } //error m_age base object private
        bool setTeacherAgeInfo(int age) {
    
     setPersonAge(age); return true; } //by Person public func set private m_age
    private:
        string m_title;

};

} /* end namespace zj001 */

namespace zj002{
    
    

class Person{
    
    
    public:
        Person(const string& name, int age ):m_name(name), m_age(age){
    
    }
        void showPersonNameInfo() const {
    
     cout << "Person name:" << m_name << endl; }
    protected:
        void showPersonAgeInfo() const {
    
     cout << "Person age:" << m_age << endl; }
        bool setPersonAge(int age) {
    
     m_age = age; return true;}
        int v_age;
    private:
        string m_name;
        int m_age;
};

class Teacher: protected Person {
    
    
    public:
        Teacher(const string name, int age, const string title):
        Person(name, age), m_title(title){
    
    }

        void showTeacherTitleInfo() const {
    
     cout << "Tech title: " << m_title << endl;  }
        bool setTeacherVirtualAge(int age) {
    
     v_age = age; return true; } // ok call protected para 
    protected:
        void showTeacherAgeInfo() const {
    
     showPersonAgeInfo(); } //protected call
        //bool setTeacherAge(int age) { m_age = age; return true; } //error m_age is private
        bool setTeacherAgeInfo(int age) {
    
     setPersonAge(age); return true; } //by Person func set private m_age
    private:
        string m_title;

};

} /* end namespace zj002*/

namespace zj003{
    
    

class Person{
    
    
    public:
        Person(const string& name, int age ):m_name(name), m_age(age){
    
    }
        void showPersonNameInfo() const {
    
     cout << "Person name:" << m_name << endl; }
    protected:
        void showPersonAgeInfo() const {
    
     cout << "Person age:" << m_age << endl; }
        bool setPersonAge(int age) {
    
     m_age = age; return true;}
        int v_age;
    private:
        string m_name;
        int m_age;
};

class Teacher: private Person {
    
    
    public:
        Teacher(const string name, int age, const string title):
        Person(name, age), m_title(title){
    
    }

        void showTeacherTitleInfo() const {
    
     cout << "Tech title: " << m_title << endl;  }
        bool setTeacherVirtualAge(int age) {
    
     v_age = age; return true; } // ok call protected para 
    protected:
        void showTeacherAgeInfo() const {
    
     showPersonAgeInfo(); } //protected call
        bool setTeacherAgeInfo(int age) {
    
     setPersonAge(age); return true; } //by Person func set private m_age
        bool setTeacherAge(int age) {
    
     v_age = age; return true; } //error m_age is private
        string v_title;
    private:
        string m_title;

};

} /* end namespace zj003*/

using namespace zj002;

int main(int argc, char** argv)
{
    
    
    Teacher tc("zhangsan", 29, "jiaoshou");

    /* using name space zj001 public 
    tc.showPersonNameInfo(); //OK public
    tc.showPersonAgeInfo(); // erro is protected within this context
    tc.m_age = 10; // is private within this context
    */

    /* using name space zj002 protected
    tc.showPersonNameInfo(); //erro  base(protected) public -> protected 
    tc.showPersonAgeInfo(); // erro is protected within this context
    tc.m_age = 10; // is private within this context
    */

    /* using name space zj003 private
    tc.showPersonNameInfo(); //erro zj003::Person' is not an accessible base(private) public -> private 
    tc.showPersonAgeInfo(); // erro is protected within this context
    tc.m_age = 10; // is private within this context
    */

    return 0;
}

三种权限也是一种集合概念,作用范围是 public > protected > private。在继承时,对派生类内部来说只有private权限与基类不同,遵循权限集合取小原则,对外部调用则完全遵循权限集合取小原则。

在这里插入图片描述

总结:
对于在没有继承情况下,在本身没有权限问题,都可以直接使用或访问方法。
在继承情况下会根据不同的继承情况,在派生类的从基类继承下来的东西才会有不同的权限。但其它总结下来也并不复杂。

  • public方式继承下来的基类权限,在派生类中不变。相当于类内部权限问题。
  • protected方式继承下来的基类权限,在派生类中都基类的public权限变为protected权限(其实在类内部权限没有变,只是在外部调用时才体现出权限的作用)。
  • private方式继承来下的基类权限,在派生类中的基类权限都变为private权限(其实在类内部权限没有变,只是在外部调用时才体现出权限的作用)。

猜你喜欢

转载自blog.csdn.net/zj646268653/article/details/108713262