中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁(yè) > news >正文

中國(guó)建設(shè)銀行寧波分行網(wǎng)站杭州seo首頁(yè)優(yōu)化軟件

中國(guó)建設(shè)銀行寧波分行網(wǎng)站,杭州seo首頁(yè)優(yōu)化軟件,仿美團(tuán)網(wǎng)站開發(fā),營(yíng)銷網(wǎng)站建設(shè)流程圖🥁作者: 華丞臧 📕????專欄:【C】 各位讀者老爺如果覺得博主寫的不錯(cuò),請(qǐng)諸位多多支持(點(diǎn)贊收藏關(guān)注)。如果有錯(cuò)誤的地方,歡迎在評(píng)論區(qū)指出。 推薦一款刷題網(wǎng)站 👉LeetCode 文章目錄一、繼承…

🥁作者: 華丞臧
📕????專欄:【C++】
各位讀者老爺如果覺得博主寫的不錯(cuò),請(qǐng)諸位多多支持(點(diǎn)贊+收藏+關(guān)注)。如果有錯(cuò)誤的地方,歡迎在評(píng)論區(qū)指出。

推薦一款刷題網(wǎng)站 👉LeetCode


文章目錄

  • 一、繼承的概念及其定義
    • 1.1 繼承的概念
    • 1.2 繼承的定義
      • 1.2.1 定義格式
      • 1.2.2 繼承關(guān)系和訪問限定符
      • 1.2.3繼承基類成員訪問方式的變化
  • 二、基類和派生類對(duì)象賦值轉(zhuǎn)換
  • 三、繼承中的作用域
  • 四、派生類的默認(rèn)成員函數(shù)
  • 五、繼承--友元和靜態(tài)成員
    • 5.1 繼承與友元
    • 5.2 繼承與static靜態(tài)成員
  • 六、復(fù)雜的菱形繼承及菱形虛擬繼承
    • 6.1 單繼承和多繼承
    • 6.2 菱形繼承
    • 6.3 虛擬繼承解決數(shù)據(jù)冗余和二義性的原理
  • 七、繼承的總結(jié)


一、繼承的概念及其定義

1.1 繼承的概念

繼承機(jī)制是面向?qū)ο蟪绦蛟O(shè)計(jì)實(shí)現(xiàn)代碼復(fù)用最重要的手段,繼承允許程序員在保持原有類特性的基礎(chǔ)上進(jìn)行擴(kuò)展,增加功能,這樣產(chǎn)生新的類,稱為派生類,原有類稱為基類。派生類也稱為子類,基類也稱為父類。

繼承呈現(xiàn)了面向?qū)ο蟪绦蛟O(shè)計(jì)的層次結(jié)構(gòu),體現(xiàn)了由簡(jiǎn)單到復(fù)雜的認(rèn)知過(guò)程。以前我們學(xué)習(xí)接觸到的復(fù)用都是函數(shù)復(fù)用,繼承是類設(shè)計(jì)層次的復(fù)用
來(lái)看下面的例子:

class Person
{
public:void Print(){cout << "name:" << _name << endl;cout << "age:" << _age << endl;}protected:string _name = "peter"; // 姓名int _age = 18;  // 年齡
};class Student : public Person
{
protected:int _stuid; // 學(xué)號(hào)
};class Teacher : public Person
{
protected:int _jobid; // 工號(hào)
};int main()
{Student s;Teacher t;s.Print();t.Print();return 0;
}

繼承后父類的Person的成員(成員函數(shù)+成員變量)都會(huì)變成子類的一部分。這里體現(xiàn)出了Student和Teacher復(fù)用了Person的成員。
在這里插入圖片描述

調(diào)用Print函數(shù)可以看到函數(shù)的復(fù)用:
在這里插入圖片描述

1.2 繼承的定義

1.2.1 定義格式

下面代碼中,Student是子類,也稱為派生類;Person是父類,也稱為基類;其中public表示繼承方式。
在這里插入圖片描述

1.2.2 繼承關(guān)系和訪問限定符

在這里插入圖片描述

1.2.3繼承基類成員訪問方式的變化

類成員/繼承方式public繼承protected繼承private繼承
基類的public成員派生類的public成員派生類的protected成員派生類的private成員
基類的protected成員派生類的protected成員派生類的protected成員派生類的private成員
基類的private成員在派生類中不可見在派生類中不可見在派生類中不可見
// 實(shí)例演示三種繼承關(guān)系下基類成員的各類型成員訪問關(guān)系的變化  
class Person
{
public :void Print (){cout<<_name <<endl;}
protected :// public/protected繼承在子類中可見,private繼承在子類中不可見string _name ; 
private :int _age ; // 在子類中不可見,但是被繼承了
};//class Student : protected Person
//class Student : private Person
class Student : public Person
{
protected :int _stunum ; // 學(xué)號(hào)
};

總結(jié):

  1. 基類private成員在子類中無(wú)論什么方式繼承都是不可見的。這里的不可見是指基類的私有成員還是被繼承到了派生類對(duì)象中,但是語(yǔ)法上限制派生類對(duì)象不管在類里面還是類外面都不能去訪問它。
  2. 基類private成員在派生類中是不能被訪問的,如果基類成員不想在類外直接被訪問,但需要在派生類中能訪問,就定義為protected,可以看出保護(hù)成員限定符就是因繼承才出現(xiàn)的。
  3. 基類的其他成員在子類的訪問方式 == Min(成員在基類的訪問限定符,繼承方式),public > protected > private。
  4. 使用關(guān)鍵字class的默認(rèn)繼承方式是private,使用struct默認(rèn)繼承方式是public,不過(guò)最好顯式的寫出繼承方式。
  5. 在實(shí)際運(yùn)用中一般使用public繼承,很少使用protected/private繼承,也不提倡使用protetced/private繼承,因?yàn)閜rotetced/private繼承下來(lái)的成員都只能在派生類的類里面使用,實(shí)際中擴(kuò)展維護(hù)性不強(qiáng)。(繼承本就是為了復(fù)用,私有代碼就不能服用了)

二、基類和派生類對(duì)象賦值轉(zhuǎn)換

  • 派生類對(duì)象可以賦值給基類的對(duì)象、基類的指針、基類的引用 在派生類對(duì)象賦值轉(zhuǎn)換時(shí),有個(gè)形象的說(shuō)法叫切片或者切割,即把派生類中的父類那部分切來(lái)賦值過(guò)去。
  • 基類對(duì)象不能賦值給派生類對(duì)象。
  • 基類的指針或者引用可以通過(guò)強(qiáng)制類型轉(zhuǎn)換賦值個(gè)派生類的指針或者引用;但是必須是基類的指針且指向派生類對(duì)象時(shí)才是安全的。這里基類如果是多態(tài)類型,可以使用RTTI(RunTime Type Information)的dynamic_cast 來(lái)進(jìn)行識(shí)別后進(jìn)行安全轉(zhuǎn)換。(這里只需先了解一下)

在這里插入圖片描述

class Person
{
public:Person(string name = "", int age = 0){_name = name;_age = age;}void Print(){cout << _name << endl;}protected:string _name; // 姓名int _age; // 年齡
};class Student : public Person
{
public:Student(int stunum = 0):Person(){_stunum = stunum;}void Show(){cout << _name << endl;cout << _age << endl;cout << _stunum << endl;}protected:int _stunum; // 學(xué)號(hào)
};int main()
{Student s;s.Show();Person* per = &s;   //發(fā)生切片//Person per = s;//Person& per = s;per->Print();// 3.基類的指針可以通過(guò)強(qiáng)制類型轉(zhuǎn)換賦值給派生類的指針per = &s;Student* ps1 = (Student*)per; // 這種情況轉(zhuǎn)換時(shí)可以的。per = &pobj;Student* ps2 = (Student*)per; // 這種情況轉(zhuǎn)換時(shí)雖然可以,但是會(huì)存在越界訪問的問題return 0;
}

在這里插入圖片描述

三、繼承中的作用域

  1. 在繼承體系中基類和派生類都有獨(dú)立的作用域。
  2. 子類和父類中有同名成員,子類成員將屏蔽父類對(duì)同名成員的直接訪問,這種情況稱為隱藏,也叫重定義。
  3. 注意:如果是成員函數(shù)的隱藏,只需要函數(shù)名相同就可以構(gòu)成隱藏。(在子類成員函數(shù)中,可以使用 基類::基類成員 顯示訪問
  4. 實(shí)際中,在繼承體系里最好不要定義同名成員。
class Person
{
protected:string _name = "小李子"; // 姓名int _num = 111;   // 身份證號(hào)
};class Student : public Person
{
public:void Print(){cout << " 姓名:" << _name << endl;cout << " 身份證號(hào):" << Person::_num << endl;cout << " 學(xué)號(hào):" << _num << endl;}
protected:int _num = 999; // 學(xué)號(hào)
};

Student的_num和Person的_num構(gòu)成隱藏關(guān)系,可以看出這樣代碼雖然能跑,但是非常容易混淆;子類中必須顯示訪問才能使用隱藏成員。
在這里插入圖片描述
再來(lái)看看成員函數(shù)的隱藏:

class A
{
public:void fun(){cout << "func()" << endl;}
};class B : public A
{
public:void fun(int i){A::fun();cout << "func(int i)->" << i << endl;}
};void Test()
{B b;b.fun(10);
};

B中的fun和A中的fun不是構(gòu)成重載,因?yàn)椴皇窃谕蛔饔糜?#xff1b;B中的fun和A中的fun構(gòu)成隱藏,成員函數(shù)滿足函數(shù)名相同就構(gòu)成隱藏
在這里插入圖片描述

四、派生類的默認(rèn)成員函數(shù)

6個(gè)默認(rèn)成員函數(shù),“默認(rèn)”的意思就是指我們不寫,編譯器會(huì)變我們自動(dòng)生成一個(gè),那么在派生類中,這幾個(gè)成員函數(shù)是如何生成的呢?

  1. 派生類的構(gòu)造函數(shù)必須調(diào)用基類的構(gòu)造函數(shù)初始化基類的那一部分成員。如果基類沒有默認(rèn)的構(gòu)造函數(shù),則必須在派生類構(gòu)造函數(shù)的初始化列表階段顯示調(diào)用。
  2. 派生類的拷貝構(gòu)造函數(shù)必須調(diào)用基類的拷貝構(gòu)造完成基類的拷貝初始化。
  3. 派生類的operator=必須要調(diào)用基類的operator=完成基類的復(fù)制。
  4. 派生類的析構(gòu)函數(shù)會(huì)在被調(diào)用完成后自動(dòng)調(diào)用基類的析構(gòu)函數(shù)清理基類成員。因?yàn)檫@樣才能保證派生類對(duì)象先清理派生類成員再清理基類成員的順序。
  5. 派生類對(duì)象初始化先調(diào)用基類構(gòu)造再調(diào)派生類構(gòu)造。
  6. 派生類對(duì)象析構(gòu)清理先調(diào)用派生類析構(gòu)再調(diào)基類的析構(gòu)。
  7. 因?yàn)楹罄m(xù)一些場(chǎng)景析構(gòu)函數(shù)需要構(gòu)成重寫,重寫的條件之一是函數(shù)名相同(暫時(shí)先了解)。那么編譯器會(huì)對(duì)析構(gòu)函數(shù)名進(jìn)行特殊處理,處理成destrutor(),所以父類析構(gòu)函數(shù)不加virtual的情況下,子類析構(gòu)函數(shù)和父類析構(gòu)函數(shù)構(gòu)成隱藏關(guān)系。

在這里插入圖片描述
在這里插入圖片描述
通過(guò)上述說(shuō)明,我們能總結(jié)一下幾點(diǎn):

  • 派生類當(dāng)中的基類部分是使用自己的構(gòu)造函數(shù)初始化,子類調(diào)用其默認(rèn)構(gòu)造函數(shù),沒有默認(rèn)構(gòu)造就必須顯示調(diào)用父類構(gòu)造;對(duì)基類數(shù)據(jù)的操作一般調(diào)用基類的成員函數(shù)。
  • 派生類的模型是基類在前,派生類的成員在后,且父類先構(gòu)造后析構(gòu),子類后構(gòu)造先析構(gòu);這是由于棧的特性所決定的,棧是先入后出的。
class Person
{
public:Person(const char* name = "peter"): _name(name){cout << "Person()" << endl;}Person(const Person& p): _name(p._name){cout << "Person(const Person& p)" << endl;}Person& operator=(const Person& p){cout << "Person operator=(const Person& p)" << endl;if (this != &p)_name = p._name;return *this;}~Person(){cout << "~Person()" << endl;}
protected:string _name; // 姓名
};class Student : public Person
{
public:Student(const char* name, int num): Person(name), _num(num){cout << "Student()" << endl;}Student(const Student& s): Person(s), _num(s._num){cout << "Student(const Student& s)" << endl;}Student& operator = (const Student& s){cout << "Student& operator= (const Student& s)" << endl;if (this != &s){Person::operator =(s);_num = s._num;}return *this;}~Student(){cout << _num;cout << ":~Student()" << endl;}protected:int _num; //學(xué)號(hào)
};
void Test()
{Student s1("jack", 18);Student s2(s1);Student s3("rose", 17);s1 = s3;
}int main()
{Test();return 0;
}

在這里插入圖片描述

五、繼承–友元和靜態(tài)成員

5.1 繼承與友元

友元關(guān)系不能繼承,也就是說(shuō)基類友元不能訪問子類私有和保護(hù)成員 。

class Student;  //聲明,Display函數(shù)向上查找Student
class Person
{
public:friend void Display(const Person& p, const Student& s);
protected:string _name; // 姓名
};
class Student : public Person
{
protected:int _stuNum; // 學(xué)號(hào)
};void Display(const Person& p, const Student& s)
{cout << p._name << endl;cout << s._stuNum << endl;
}
void test()
{Person p;Student s;Display(p, s);
}

程序無(wú)法運(yùn)行成功,Student成員變量_stuNum是保護(hù)成員,在基類Person的友元中是無(wú)法被訪問的。
在這里插入圖片描述

5.2 繼承與static靜態(tài)成員

基類定義了static靜態(tài)成員,則整個(gè)繼承體系里面只有一個(gè)這樣的成員。無(wú)論派生出多少個(gè)子類,都只有一個(gè)static成員實(shí)例 。

六、復(fù)雜的菱形繼承及菱形虛擬繼承

6.1 單繼承和多繼承

一個(gè)子類只有一個(gè)直接父類時(shí)稱這個(gè)繼承關(guān)系為單繼承

前面我們看到的都是單繼承,單繼承并不是說(shuō)只有兩個(gè)類,而是類之間的基礎(chǔ)關(guān)系是線性的,即一個(gè)父親只有一個(gè)兒子,如下圖:

在這里插入圖片描述

一個(gè)子類有兩個(gè)或兩個(gè)以上直接父類時(shí)稱這個(gè)繼承關(guān)系為多繼承。

在這里插入圖片描述

6.2 菱形繼承

菱形繼承是多繼承的一種特殊情況。

在這里插入圖片描述

class Person
{
protected:string _name; // 姓名
};class Student : public Person
{
protected:int _stuNum; // 學(xué)號(hào)
};class Teacher : public Person
{
protected:int _id; // 職工編號(hào)
};class Assistant : public Student, public Teacher{
protected:string _majorCourse;  // 主修課程
};

通過(guò)監(jiān)視窗口觀察到,子類對(duì)象中存在兩份Person數(shù)據(jù),如下圖:
在這里插入圖片描述

在C++中支持多繼承,因此就會(huì)存在菱形繼承;菱形繼承就是子類繼承的多個(gè)父類當(dāng)中繼承了相同的類。這里就存在一個(gè)問題:當(dāng)子類繼承的多個(gè)父類中繼承了相同的類,那么就子類應(yīng)該繼承那一個(gè)呢,還是說(shuō)兩個(gè)繼承。

從下面的對(duì)象成員模型構(gòu)造,可以看出菱形繼承有數(shù)據(jù)冗余和二義性的問題,在Assistant的對(duì)象中Person成員會(huì)有兩份。

在這里插入圖片描述
C++提供了virtual關(guān)鍵字,用來(lái)定義虛擬函數(shù)和虛繼承;虛擬繼承可以解決菱形繼承的二義性和數(shù)據(jù)冗余問題。如上面的繼承關(guān)系,在Student和Teacher繼承Person時(shí)使用虛擬繼承即可解決問題。注意:虛擬繼承不要在其他地方去使用。

class Person
{
public:string _name; // 姓名
};
class Student : virtual public Person //虛擬繼承
{
protected:int _num; //學(xué)號(hào)
};
class Teacher : virtual public Person
{
protected:int _id; // 職工編號(hào)
};
class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修課程
};

6.3 虛擬繼承解決數(shù)據(jù)冗余和二義性的原理

為了研究虛擬繼承原理,我們給出了一個(gè)簡(jiǎn)化的菱形繼承繼承體系,再借助內(nèi)存窗口觀察對(duì)象成員的模型。

class A
{
public:int _a;
};class B : public A
// class B : virtual public A
{
public:int _b;
};class C : public A// class C : virtual public A
{
public:int _c;
};class D : public B, public C
{
public:int _d;
};int main()
{D d;d.B::_a = 1;d.C::_a = 2;d._b = 3;d._c = 4;d._d = 5;return 0;
}

下圖是菱形繼承的內(nèi)存對(duì)象成員模型,可以看到數(shù)據(jù)冗余:
在這里插入圖片描述

下圖是菱形虛擬繼承的內(nèi)存對(duì)象成員模型:這里可以分析出D對(duì)象中將A放到的了對(duì)象組成的最下面,這個(gè)A同時(shí)屬于B和C,那么B和C如何去找到公共的A呢?這里是通過(guò)了B和C的兩個(gè)指針,指向的一張表。這兩個(gè)指針叫虛基表指針,這兩個(gè)表叫虛基表。虛基表中存的偏移量。通過(guò)偏移量可以找到下面的A。
在這里插入圖片描述

B和C通過(guò)對(duì)象中的虛基表指針找到偏移量,再通過(guò)偏移量找到A。
在這里插入圖片描述

下面是上面的Person關(guān)系菱形虛擬繼承的原理解釋:
在這里插入圖片描述

七、繼承的總結(jié)

  1. C++語(yǔ)法復(fù)雜,多繼承就是一個(gè)體現(xiàn)。有了多繼承,就存在菱形繼承,有了菱形繼承就有菱形虛擬繼承,底層實(shí)現(xiàn)就很復(fù)雜。所以一般不建議設(shè)計(jì)出多繼承,一定不要設(shè)計(jì)出菱形繼承,否則在復(fù)雜度及性能上都有問題。

  2. 繼承和組合

    • public繼承是一種is-a的關(guān)系。也就是說(shuō)每個(gè)派生類對(duì)象都是一個(gè)基類對(duì)象。
    • 組合是一種has-a的關(guān)系。假設(shè)B組合了A,每個(gè)B對(duì)象中都有一個(gè)A對(duì)象。
    • 繼承允許你根據(jù)基類的實(shí)現(xiàn)來(lái)定義派生類的實(shí)現(xiàn)。這種通過(guò)生成派生類的復(fù)用通常被稱為白箱復(fù)用(white-box reuse)。術(shù)語(yǔ)“白箱”是相對(duì)可視性而言:在繼承方式中,基類的內(nèi)部細(xì)節(jié)對(duì)子類可見 。繼承一定程度破壞了基類的封裝,基類的改變,對(duì)派生類有很大的影響。派生類和基類間的依賴關(guān)系很強(qiáng),耦合度高。
    • 對(duì)象組合是類繼承之外的另一種復(fù)用選擇。新的更復(fù)雜的功能可以通過(guò)組裝或組合對(duì)象來(lái)獲得。對(duì)象組合要求被組合的對(duì)象具有良好定義的接口。這種復(fù)用風(fēng)格被稱為黑箱復(fù)用(black-box reuse),因?yàn)閷?duì)象的內(nèi)部細(xì)節(jié)是不可見的。對(duì)象只以“黑箱”的形式出現(xiàn)。組合類之間沒有很強(qiáng)的依賴關(guān)系,耦合度低。優(yōu)先使用對(duì)象組合有助于你保持每個(gè)類被封裝。
    • 實(shí)際盡量多去用組合。組合的耦合度低,代碼維護(hù)性好。不過(guò)繼承也有用武之地的,有些關(guān)系就適合繼承那就用繼承,另外要實(shí)現(xiàn)多態(tài),也必須要繼承。類之間的關(guān)系可以用繼承,可以用組合,就用組合。
// Car和BMW Car和Benz構(gòu)成is-a的關(guān)系
class Car
{
protected:string _colour = "白色"; // 顏色string _num = "陜ABIT00"; // 車牌號(hào)
};class BMW : public Car
{
public:void Drive() {cout << "好開-操控" << endl;}
};class Benz : public Car
{
public:void Drive() {cout << "好坐-舒適" << endl;}
};// Tire和Car構(gòu)成has-a的關(guān)系class Tire
{
protected:string _brand = "Michelin";  // 品牌size_t _size = 17;         // 尺寸};class Car
{
protected:string _colour = "白色"; // 顏色string _num = "陜ABIT00"; // 車牌號(hào)Tire _t; // 輪胎
}; 
http://www.risenshineclean.com/news/61786.html

相關(guān)文章:

  • 動(dòng)態(tài)設(shè)計(jì)網(wǎng)站寧波網(wǎng)站建設(shè)團(tuán)隊(duì)
  • 石家莊網(wǎng)站制作倉(cāng)谷在線培訓(xùn)
  • aspnet動(dòng)態(tài)網(wǎng)站開發(fā)題目建網(wǎng)站有哪些步驟
  • 西寧網(wǎng)站seo外包360指數(shù)查詢
  • 網(wǎng)絡(luò)公司做的網(wǎng)站我能改后臺(tái)么免費(fèi)做網(wǎng)站怎么做網(wǎng)站嗎
  • 淘寶網(wǎng)站框架seo發(fā)帖工具
  • 知名網(wǎng)站有哪些?百度推廣技巧
  • 清遠(yuǎn)新聞最新長(zhǎng)沙seo計(jì)費(fèi)管理
  • 網(wǎng)站建設(shè)注意什么小程序推廣平臺(tái)
  • 建設(shè)網(wǎng)站寶安區(qū)短視頻營(yíng)銷推廣方案
  • 做百度微信小程序都有哪些網(wǎng)站百度上做推廣怎么收費(fèi)
  • 做網(wǎng)站服務(wù)器需要系統(tǒng)全國(guó)新冠疫情最新消息
  • 小網(wǎng)站如何做密碼找回福州seo網(wǎng)絡(luò)推廣
  • 下載網(wǎng)站源碼拼多多運(yùn)營(yíng)
  • 購(gòu)物網(wǎng)站app制作aso優(yōu)化什么意思
  • 系統(tǒng)開發(fā)包括什么seo百度推廣
  • 模板網(wǎng)站可以自己買空間嗎嗎百度一下全知道
  • 網(wǎng)站欄目頁(yè)如何做網(wǎng)絡(luò)推廣平臺(tái)公司
  • 做網(wǎng)站平面模板是啥意思互動(dòng)營(yíng)銷案例分析
  • php網(wǎng)站開發(fā)實(shí)例教程簡(jiǎn)介關(guān)鍵詞優(yōu)化怎么優(yōu)化
  • 在線安卓軟件開發(fā)優(yōu)化大師官網(wǎng)下載
  • 做優(yōu)化很好的網(wǎng)站常德政府網(wǎng)站市民留言
  • 深圳做網(wǎng)站的給說(shuō)各種網(wǎng)站
  • 寧波網(wǎng)站優(yōu)化軟件網(wǎng)絡(luò)推廣seo怎么做
  • 網(wǎng)站程序是如何開發(fā)的百度搜索引擎優(yōu)化
  • 做的網(wǎng)站怎樣更新百度競(jìng)價(jià)點(diǎn)擊一次多少錢
  • 福建設(shè)備公司網(wǎng)站百度24小時(shí)人工電話
  • 網(wǎng)站軟文偽原創(chuàng)企業(yè)營(yíng)銷策略有哪些
  • 東莞網(wǎng)上商城網(wǎng)站建設(shè)南京seo公司
  • 河南省建設(shè)人才信息網(wǎng)官網(wǎng)自助優(yōu)化排名工具