C++的三種訪問權限與三種繼承方式

轉自[陽光日誌]的博客《C++的三種訪問權限與三種繼承方式》

三種訪問權限

我們知道C++中的類,有三種訪問權限(也稱作訪問控制),它們分別是public、protected、private。要理解它們其實也很容易,看下面了一個例子。
父類:

class Person
{
public:
    Person(const string& name, int age) : m_name(name), m_age(age)
    {
    }

    void ShowInfo()
    {
        cout << "姓名:" << m_name << endl;
        cout << "年齡:" << m_age << endl;
    }

protected:
    string  m_name;     //姓名

private:
    int     m_age;      //年齡
};

子類:

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

    void ShowTeacherInfo()
    {
        ShowInfo();                             //正確,public屬性子類可見
        cout << "姓名:" << m_name << endl;        //正確,protected屬性子類可見
        cout << "年齡:" << m_age << endl;     //錯誤,private屬性子類不可見

        cout << "職稱:" << m_title << endl;   //正確,本類中可見自己的所有成員
    }

private:
    string  m_title;        //職稱
};

調用方:

void test()
{
    Person person("張三", 22);
    person.ShowInfo();                  //public屬性,對外部可見
    cout << person.m_name << endl;      //protected屬性,對外部不可見
    cout << person.m_age << endl;       //private屬性,對外部不可見
}

總結

我們對C++類三種方式控制權限總結如下,這與Java中的三種對應的訪問權限是一樣的。

訪問權限 public protected private
對本類 可見 可見 可見
對子類 可見 可見 不可見
對外部(調用方) 可見 不可見 不可見

三種繼承方式

C++中繼承的方式還有多種,也分別都用public、protected、private表示。這與Java不一樣,Java只有繼承的概念,默認是public繼承的。
1. 三種繼承方式不影響子類對父類的訪問權限,子類對父類只看父類的訪問控制權。如下面三種繼承方式都能訪問父類中的public和protected成員。

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

    void ShowTeacherInfo()
    {
        ShowInfo();                             //正確,public屬性子類可見
        cout << "姓名:" << m_name << endl;        //正確,protected屬性子類可見
        //cout << "年齡:" << m_age << endl;       //錯誤,private屬性子類不可見

        cout << "職稱:" << m_title << endl;   //正確,本類中可見自己的所有成員
    }

private:
    string  m_title;        //職稱
};
  1. 繼承方式是爲了控制子類(也稱派生類)的調用方(也叫用戶)對父類(也稱基類)的訪問權限。

public繼承

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

    void ShowTeacherInfo()
    {
        ShowInfo();                             //正確,public屬性子類可見
        cout << "職稱:" << m_title << endl;   //正確,本類中可見自己的所有成員
    }

private:
    string  m_title;        //職稱
};

void TestPublic()
{
    Teacher teacher("李四", 35, "副教授");
    teacher.ShowInfo();
    cout << endl;
    teacher.ShowTeacherInfo();
}

結果:
姓名:李四
年齡:35

姓名:李四
年齡:35
職稱:副教授

private繼承:

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

    void ShowTeacherInfo()
    {
        ShowInfo();                             //正確,public屬性子類可見
        cout << "職稱:" << m_title << endl;   //正確,本類中可見自己的所有成員
    }

private:
    string  m_title;        //職稱
};

void TestPrivate()
{
    Teacher teacher("李四", 35, "副教授");
    teacher.ShowInfo();             //錯誤,因爲Teacher採用了private的繼承方式,外部不可訪問。
    cout << endl;
    teacher.ShowTeacherInfo();
}
  1. public、protected、private三種繼承方式,相當於把父類的public訪問權限在子類中變成了對應的權限。 如protected繼承,把父類中的public成員在本類中變成了protected的訪問控制權限;private繼承,把父類的public成員和protected成員在本類中變成了private訪問控制權。

protected繼承:

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

    void ShowTeacherInfo()
    {
        ShowInfo();                             //正確,public屬性子類可見
        cout << "職稱:" << m_title << endl;   //正確,本類中可見自己的所有成員
    }

private:
    string  m_title;        //職稱
};

void TestProtected()
{
    Teacher teacher("李四", 35, "副教授");
    teacher.ShowInfo();         //錯誤,基類Person的ShowInfo此時對Teacher相當於protected的,外部不可以被訪問
    cout << endl;
    teacher.ShowTeacherInfo();
}

class Leader : public Teacher
{
public:
    Leader(const string& name, int age, const string& title, string position)
        : Teacher(name, age, title), m_position(position)
    {
    }

    void ShowLeaderInfo()
    {
        ShowInfo();             //基類Person的ShowInfo此時相當於protected的,但子類仍可以訪問
        ShowTeacherInfo();      //ShowTeacherInfo仍然是public的,可以訪問
        cout << m_position << endl;
    }

private:
    string m_position;
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章