C++三种继承方式
斜體樣式???繼承方式限定了基類成員在派生類中的訪問權限,包括 public(公有的)、private(私有的)和 protected(受保護的)。此項是可選項,如果不寫,默認為 private(成員變量和成員函數默認也是 private)。
現在我們知道,public、protected、private 三個關鍵字除了可以修飾類的成員,還可以指定繼承方式
public、protected、private 指定繼承方式
不同的繼承方式會影響基類成員在派生類中的訪問權限。
1) public繼承方式
- 基類中所有 public 成員在派生類中為 public 屬性;
- 基類中所有 protected 成員在派生類中為 protected 屬性;
- 基類中所有 private 成員在派生類中不能使用。
2) protected繼承方式
- 基類中的所有 public 成員在派生類中為 protected 屬性;
- 基類中的所有 protected 成員在派生類中為 protected 屬性;
- 基類中的所有 private 成員在派生類中不能使用。
3) private繼承方式
- 基類中的所有 public 成員在派生類中均為 private 屬性;
- 基類中的所有 protected 成員在派生類中均為 private 屬性;
- 基類中的所有 private 成員在派生類中不能使用。
通過上面的分析可以發現:
基類成員在派生類中的訪問權限不得高于繼承方式中指定的權限。例如,當繼承方式為 protected 時,那么基類成員在派生類中的訪問權限最高也為 protected,高于 protected 的會降級為 protected,但低于 protected 不會升級。再如,當繼承方式為 public 時,那么基類成員在派生類中的訪問權限將保持不變。
也就是說,繼承方式中的 public、protected、private 是用來指明基類成員在派生類中的最高訪問權限的。
不管繼承方式如何,基類中的 private 成員在派生類中始終不能使用(不能在派生類的成員函數中訪問或調用)。
如果希望基類的成員能夠被派生類繼承并且毫無障礙地使用,那么這些成員只能聲明為 public 或 protected;只有那些不希望在派生類中使用的成員才聲明為 private。
如果希望基類的成員既不向外暴露(不能通過對象訪問),還能在派生類中使用,那么只能聲明為 protected。
注意,我們這里說的是基類的 private 成員不能在派生類中使用,并沒有說基類的 private 成員不能被繼承。實際上,基類的 private 成員是能夠被繼承的,并且(成員變量)會占用派生類對象的內存,它只是在派生類中不可見,導致無法使用罷了。private 成員的這種特性,能夠很好的對派生類隱藏基類的實現,以體現面向對象的封裝性。
| public繼承 | public | protected | 不可見 |
| protected繼承 | protected | protected | 不可見 |
| private繼承 | private | private | 不可見 |
由于 private 和 protected 繼承方式會改變基類成員在派生類中的訪問權限,導致繼承關系復雜,所以實際開發中我們一般使用 public。
#include<iostream> using namespace std; //基類People class People{ public:void setname(char *name);void setage(int age);void sethobby(char *hobby);char *gethobby(); protected:char *m_name;int m_age; private:char *m_hobby; }; void People::setname(char *name){ m_name = name; } void People::setage(int age){ m_age = age; } void People::sethobby(char *hobby){ m_hobby = hobby; } char *People::gethobby(){ return m_hobby; } //派生類Student class Student: public People{ public:void setscore(float score); protected:float m_score; }; void Student::setscore(float score){ m_score = score; } //派生類Pupil class Pupil: public Student{ public:void setranking(int ranking);void display(); private:int m_ranking; }; void Pupil::setranking(int ranking){ m_ranking = ranking; } void Pupil::display(){cout<<m_name<<"的年齡是"<<m_age<<",考試成績為"<<m_score<<"分,班級排名第"<<m_ranking<<",TA喜歡"<<gethobby()<<"。"<<endl; } int main(){Pupil pup;pup.setname("小明");pup.setage(15);pup.setscore(92.5f);pup.setranking(4);pup.sethobby("乒乓球");pup.display();return 0; }運行結果:
小明的年齡是15,考試成績為92.5分,班級排名第4,TA喜歡乒乓球。這是一個多級繼承的例子,Student 繼承自 People,Pupil 又繼承自 Student,它們的繼承關系為 People --> Student --> Pupil。Pupil 是最終的派生類,它擁有基類的 m_name、m_age、m_score、m_hobby 成員變量以及 setname()、setage()、sethobby()、gethobby()、setscore() 成員函數。
注意,在派生類 Pupil 的成員函數 display() 中,我們借助基類的 public 成員函數 gethobby() 來訪問基類的 private 成員變量 m_hobby,因為 m_hobby 是 private 屬性的,在派生類中不可見,所以只能借助基類的 public 成員函數 sethobby()、gethobby() 來訪問。
在派生類中訪問基類 private 成員的唯一方法就是借助基類的非 private 成員函數,如果基類沒有非 private 成員函數,那么該成員在派生類中將無法訪問。
改變訪問權限
-
使用 using 關鍵字可以改變基類成員在派生類中的訪問權限,例如將 public 改為 private、將 protected 改為 public。
-
注意:using 只能改變基類中 public 和 protected 成員的訪問權限,不能改變 private 成員的訪問權限,因為基類中 private 成員在派生類中是不可見的,根本不能使用,所以基類中的 private 成員在派生類中無論如何都不能訪問。
代碼中首先定義了基類 People,它包含兩個 protected 屬性的成員變量和一個 public 屬性的成員函數。定義 Student 類時采用 public 繼承方式,People 類中的成員在 Student 類中的訪問權限默認是不變的。
不過,我們使用 using 改變了它們的默認訪問權限,如代碼第 21~25 行所示,將 show() 函數修改為 private 屬性的,是降低訪問權限,將 name、age 變量修改為 public 屬性的,是提高訪問權限。
因為 show() 函數是 private 屬性的,所以代碼第 36 行會報錯。把該行注釋掉,程序輸出結果為:
我是小明,今年16歲,這次考了99.5分!
總結
- 上一篇: C++继承和派生简明教程
- 下一篇: C++继承时的名字遮蔽(一)