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