C++ 類的繼承與派生(四)小結(jié)

注意:本文中代碼均使用 Qt 開發(fā)編譯環(huán)境
類的繼承與派生?
以原有的類為基礎(chǔ)產(chǎn)生新的類,我們就說新類繼承了原有類的特征铸敏,也可以說從原有類派生出新類。

類的繼承與派生好處悟泵?
提高了代碼的重用性和可擴展性杈笔。

派生新類的過程一般包括?
吸收已有類的成員糕非、調(diào)整已有類的成員和添加新的成員三個步驟蒙具。

在C++中,派生類的一般定義語法為朽肥?
class 派生類名:繼承方式 基類名1,繼承方式 基類名2,...,繼承方式 基類名n
{
派生類成員聲明; //是指除了從基類繼承來的所有成員之外禁筏,新增加的數(shù)據(jù)和函數(shù)成員
};

一個派生類可以同時有多個基類,這種情況稱為多繼承衡招。一個派生類只有一個基類的情況篱昔,成為單繼承。
單繼承可以看作是多繼承的一個最簡單的特例,多繼承可以看成是單繼承的組合州刽。

例子:

class employee {

protected:
    char name[20];              // 姓名
    int individualEmpNo;        // 個人編號
    int grade;                  // 級別
    float accumPay;             // 月薪總額
    static int employeeNo;      // 本公司職員編號目前最大值



public:
    employee();
    ~employee();

    void pay();                 // 計算月薪函數(shù)
    void promote(int);          // 升級函數(shù)
    void SetName(char *);       // 設(shè)置姓名
    char * GetName();           // 提取姓名
    int GetindividualEmpNo();   // 提取編號
    int Getgrade();             // 提取級別
    float GetaccumPay();        // 提取月薪
};


class technician:public employee {  // 兼職技術(shù)人員類

private:
    float hourlyRate;           // 每小時酬金    派生類新增
    int workHours;              // 當(dāng)月工作時數(shù)   派生類新增

public:
    technician();
    void SetworkHours(int wh);  // 設(shè)置工作時數(shù)   派生類新增
    void pay();                 // 計算月薪函數(shù)   同名隱藏    隱藏基類
};

派生類過程:
1.吸收基類成員
這樣撩银,派生類實際上就包含了基類中除構(gòu)造函數(shù)和析構(gòu)函數(shù)之外的所有成員只嚣。在派生類的過程中構(gòu)造函數(shù)和析構(gòu)函數(shù)都不被繼承矗积。

2.改造基類成員
包括兩個方面:一個是基類成員的訪問控制問題客蹋,主要依靠派生類定義時的繼承方式來控制;第二個是對基類數(shù)據(jù)或函數(shù)成員的隱藏匹表,就是在派生類中聲明一個和基類數(shù)據(jù)或函數(shù)同名的成員门坷,例如例子中的pay()。此時使用成員名就只能訪問到派生類中聲明的同名成員袍镀,這稱作同名隱藏拜鹤。

3.添加新的成員
派生類新成員的加入是繼承與派生機制的核心,是保證派生類在功能上有所發(fā)展的關(guān)鍵流椒。

訪問控制###

類的繼承方式有public、protected明也、private三種宣虾,不同的繼承方式,導(dǎo)致原來具有不同訪問屬性的基類成員在派生類中的訪問屬性也有所不同温数。

這里所說的訪問來自兩個方面:
一是派生類中新增的成員訪問從基類繼承的成員绣硝;
二是在派生類外部(非類族內(nèi)的成員),通過派生類的對象訪問從基類繼承的成員撑刺。

<public>
當(dāng)類的繼承方式為公有繼承時鹉胖,基類的公有和保護成員的訪問屬性在派生類中不變,而基類的私有成員不可直接訪問够傍。

解釋:
基類的公有成員和保護成員被繼承到派生類中訪問屬性不變甫菠,仍作為派生類的公有成員和保護成員,派生類的其他成員可以直接訪問他們冕屯。
在類族之外只能通過派生類的對象訪問從基類繼承的公有成員寂诱,而無論是派生類的成員還是派生類的對象都無法直接訪問基類的私有成員。

示例:
// rectangle.h 文件

#ifndef RECTANGLE_H
#define RECTANGLE_H

class Point {

public:
    void InitP(float xx = 0, float yy = 0) {
        X = xx;
        Y = yy;
    }

    void Move(float xOff,float yOff) {
        X += xOff;
        Y += yOff;
    }

    float GetX() { return X; }

    float GetY() { return Y; }

private:
    float X,Y;
};

class Rectangle : public Point {

public:
    void InitR(float x,float y,float w,float h) {
        InitP(x,y);
        W = w;
        H = h;
    }

    float GetH(){return H;}

    float getW(){return W;}

private:
    float W,H;
};

#endif // RECTANGLE_H

// .cpp 部分

#include <QCoreApplication>
#include <QDebug>
#include "rectangle.h"

int main()
{
    Rectangle rect;

    rect.InitR(2,3,20,10);
    rect.Move(3,2);

    qDebug() << "The data of rect(X,Y,W,H):"
             << rect.GetX() << "," << rect.GetY() << ","
             << rect.getW() << "," << rect.GetH();

    return 0;
}

運行結(jié)果:


運行結(jié)果

<private>
當(dāng)類的繼承方式為私有繼承時安聘,基類中的公有成員和保護成員都以私有成員身份出現(xiàn)在派生類中痰洒,而基類的私有成員在派生類中不可以直接訪問。

解釋:
基類的公有和保護成員被繼承后作為派生類的私有成員浴韭,派生類的其他成員可以直接訪問它們丘喻,但是在類族外部通過派生類的對象無法直接訪問它們。
無論是派生類的成員還是通過派生類的對象念颈,都無法直接訪問從基類繼承的私有成員泉粉。這也就是說,該種繼承方式舍肠,阻止了基類功能的繼續(xù)派生搀继。

示例:
//Rectangle.h

#ifndef RECTANGLE_H
#define RECTANGLE_H

class Point {

public:
    void InitP(float xx = 0, float yy = 0) {
        X = xx;
        Y = yy;
    }

    void Move(float xOff,float yOff) {
        X += xOff;
        Y += yOff;
    }

    float GetX() { return X; }

    float GetY() { return Y; }

private:
    float X,Y;
};

class Rectangle : private Point {

public:
    void InitR(float x,float y,float w,float h) {
        InitP(x,y);
        W = w;
        H = h;
    }

    void Move(float xOff,float yOff){
        Point::Move(xOff,yOff);
    }

    float GetX(){return Point::GetX();}

    float GetY(){return Point::GetY();}

    float GetH(){return H;}

    float getW(){return W;}

private:
    float W,H;
};

#endif // RECTANGLE_H

// .cpp 部分與上一個示例中的相同

1.派生類的成員函數(shù)及對象無法直接訪問積累的私有成員(例如X窘面,Y)。
2.派生類的成員仍可以訪問到從基類繼承過來的公有和保護成員(例如在派生類函數(shù)成員InitR中直接調(diào)用基類的函數(shù)InitP)叽躯。
3.但是在類外部通過派生類的對象根本無法直接訪問到積累的任何成員财边,積累原有的外部接口(例如基類的GetX()和GetY()函數(shù))被派生類封裝和隱藏起來。

在私有繼承的情況下点骑,為了保證基類的一部分外部接口特征能夠在派生類中也存在酣难,就必須在派生類中重新聲明同名的成員。這里在派生類Rectangle中黑滴,重新聲明了Move憨募,GetX()和GetY()等函數(shù),利用派生類對基類成員的訪問能力袁辈,把基類的原有成員函數(shù)的功能照搬過來菜谣。

這種在派生類中重新聲明的成員函數(shù)具有比基類同名成員函數(shù)更小的作用域,因此在調(diào)用時晚缩,根據(jù)同名隱藏的原則尾膊,自然會調(diào)用派生類的函數(shù)。

<protected>
保護繼承中荞彼,基類的公有和保護成員都以保護成員的身份出現(xiàn)在派生類中冈敛,而基類的私有成員不可直接訪問。

解釋:
派生類的其他成員可以直接訪問從基類繼承來的公有和保護成員鸣皂,但是在類外部通過派生類的對象無法直接訪問它們抓谴。

無論是派生類的成員還是通過派生類的對象,都無法直接訪問從基類繼承的私有成員寞缝。

基類中的保護成員有可能被它的派生類訪問癌压,但是絕不可能被其他外部使用者(比如程序中的普通函數(shù)、與基類平行的其它類等)訪問荆陆。

示例1:

class A {

protected:
    int x;
};

int main()
{
    A a;
    a.x = 5;    // 錯誤措拇!
    return 0;
}

在A類對象a的模塊中是無法訪問A類的保護成員的,這種情況下慎宾,保護成員和私有成員一樣得到了很好的隱藏丐吓。

示例2:
如果A類以公有方式派生產(chǎn)生了B類,則在B類中趟据,A類保護成員和該類的公有成員一樣是可以訪問的券犁。例如:

class A {

protected:
    int x;
};

class B : public A {

public:
    void function();
};

void B::function() {
    x = 5;  // 正確
}

int main()
{
    B b;
    b.function();
    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市汹碱,隨后出現(xiàn)的幾起案子粘衬,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件稚新,死亡現(xiàn)場離奇詭異勘伺,居然都是意外死亡,警方通過查閱死者的電腦和手機褂删,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進店門飞醉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人屯阀,你說我怎么就攤上這事缅帘。” “怎么了难衰?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵钦无,是天一觀的道長。 經(jīng)常有香客問我盖袭,道長失暂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任鳄虱,我火速辦了婚禮趣席,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘醇蝴。我一直安慰自己,他們只是感情好想罕,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布悠栓。 她就那樣靜靜地躺著,像睡著了一般按价。 火紅的嫁衣襯著肌膚如雪惭适。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天楼镐,我揣著相機與錄音癞志,去河邊找鬼。 笑死框产,一個胖子當(dāng)著我的面吹牛凄杯,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播秉宿,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼戒突,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了描睦?” 一聲冷哼從身側(cè)響起膊存,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后隔崎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體今艺,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年爵卒,在試婚紗的時候發(fā)現(xiàn)自己被綠了虚缎。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡技潘,死狀恐怖遥巴,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情享幽,我是刑警寧澤铲掐,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站值桩,受9級特大地震影響摆霉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜奔坟,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一携栋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧咳秉,春花似錦婉支、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至炕舵,卻和暖如春何之,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背咽筋。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工溶推, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人奸攻。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓蒜危,卻偏偏與公主長得像,于是被迫代替她去往敵國和親睹耐。 傳聞我的和親對象是個殘疾皇子舰褪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容