C++学习 十五、类继承(1)基类,派生类,访问权限,protected
C++學習 十五、類繼承(1)基類,派生類
- 前言
- 類繼承
- 類的關系與繼承
- 基類, 派生類
- 基類
- 派生類
- 構造函數,析構函數
- 文件位置
- 訪問權限
- protected
- 后記
前言
本篇開始學習C++類的繼承。
類繼承
C++的類繼承用于描述一種is的關系。is關系,比如橘子是水果,猴子是動物。
類S是另一個類F的衍生,通過類繼承的關系,就能夠在F類的基礎上,增量修改得到類S。類F稱為基類,S稱為派生類。
派生類繼承了基類的數據和方法,并且能夠添加數據和方法。
類的關系與繼承
類與類的關系決定了是否適合繼承。
b is a關系:橘子是水果。
b has a關系:晚餐有水果。
b uses a關系:空調使用遙控。
b is like a關系:空調類似洗衣機(都是家具)。
上面的關系中,is關系適合使用b類繼承a類;has關系適合在類b中使用a作為數據成員;uses關系適合將類b作為a的友元;is like關系適合定義一個包含a,b共有特征的類c,然后考慮c與a,b的關系。
基類, 派生類
基類
被繼承的類是基類,可以按照之前定義類的方法,提供數據成員和方法。這里直接提供一個簡單的基類Base:
class Base{private:int a_;double b_;public:Base();Base(int, double);void print(); };Base::Base():a_(1), b_(1.){std::cout << "Base default constructor\n"; }Base::Base(int a, double b): a_(a), b_(b){std::cout << "Base constructor\n"; }void Base::print(){std::cout << a_ << " " << b_ << std::endl; }派生類
繼承聲明為:
class 派生類名 : 繼承方式 基類名 {};,如class Derived : public Base {};
繼承方式限定了派生類對基類成員的訪問權限。public繼承,基類的公有成員能夠被派生類訪問,但基類的私有成員只能被基類的公有方法和保護方法訪問。
派生類將繼承基類的所有數據成員以及成員函數。派生類還可以添加額外的成員
派生類雖然繼承了基類的構造函數,但需要定義自己的構造函數。
下面從Base類派生一個Derived類:
class Derived : public Base{private:int a_;double c_;public:Derived();Derived(int, double, int, double);void print(); };Derived::Derived(): Base(), a_(1), c_(1.){std::cout <<"Derived default constructor\n"; }Derived::Derived(int a0, double b, int a1, double c) :Base(a0, b), a_(a1), c_(c) {std::cout <<"Derived constructor\n"; }void Derived::print(){Base::print();std::cout <<a_ << " " << c_ << std::endl; }構造函數,析構函數
創建派生類對象時將調用派生類的構造函數,因此必須為派生類提供構造函數。派生類的構造函數應當為添加的數據成員和繼承的數據成員初始化。
后面訪問權限中會提到,派生類不能直接訪問基類的私有成員,必須通過基類方法來訪問。派生類的構造函數必須調用基類構造函數。
構造函數Derived::Derived()是手動提供的默認構造函數,在成員初始化列表中調用了基類的構造函數Base()。
創建派生類對象時,程序會首先創建基類對象,然后再創建派生類對象:
Derived son1(2, 2.2, 3, 3.3); /* Base constructor Derived constructor 2 2.2 3 3.3 Derived destructor Base destructor */上面的語句將參數傳入派生類構造函數Derived(int a0, double b, int a1, double c),然后Derived函數調用基類構造函數Base(int, double),創建了一個嵌套的Base對象,存儲基類的數據Base::a_, Base::b;然后再回到派生類構造函數,創建一個Derived對象,存儲派生類的數據Derived::a_, Derived::c_。
在派生類對象過期時,程序首先調用派生類析構函數,再調用基類析構函數。
派生類構造函數的成員初始化列表如果沒有顯式調用基類構造函數,創建對象時將調用基類的默認構造函數:
Derived son2; /* Base default constructor Derived default constructor Derived destructor Base destructor */注意:如果創建派生類對象時,要指定繼承成員的值,則必須在派生類構造函數的成員初始化列表中調用基類構造函數。派生類構造函數一定會調用一個基類構造函數。
小結一下派生類的構造函數:
- 首先向基類構造函數傳參
- 創建基類對象,基類對象存儲繼承成員值
- 隨后創建派生類對象,派生類對象存儲添加成員的值
文件位置
編譯器必須在聲明派生類前知道基類的結構。因此,通常把基類聲明和派生類聲明放在同一個頭文件中,把基類和派生類方法定義放在同一個源文件中。
訪問權限
類繼承中的一大難點在于,繼承后派生類對基類成員的訪問權限。
繼承方式包括public,protected,private三類。不過絕大多數情況,都使用public繼承。
對于類自身的成員而言:
| public | 能直接被外部訪問 |
| protected | 能被該類和子類的方法訪問 |
| private | 僅能被該類的方法訪問 |
當派生類繼承基類時,根據不同的繼承方式,派生類對基類成員的訪問權限將發生變化:
| public 權限 | public | protected | private |
| protected 權限 | protected | protected | private |
| private 權限 | private | private | private |
protected
protected權限是與繼承密切相關的訪問權限。protected成員不能被外部直接訪問,但可以被該類以及子類的成員函數訪問。protected使得派生類能夠使用公眾不能使用的內部成員。
注意:如果希望限制數據的可見性,則最好使用private訪問權限而不是protected,并且提供派生類能夠調用的基類方法來訪問基類的數據。
后記
下篇學習類的繼承,虛函數與多態。
總結
以上是生活随笔為你收集整理的C++学习 十五、类继承(1)基类,派生类,访问权限,protected的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: EFcore Find和single的区
- 下一篇: R语言-数据预处理