日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

复习笔记(四)——C++继承

發(fā)布時間:2025/3/21 c/c++ 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 复习笔记(四)——C++继承 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

  • 基類與派生類
  • 繼承和派生(難點)
    • 派生類的聲明
    • 類成員的訪問權(quán)限(回顧)
    • 基類中的私有成員
    • 派生類的三種繼承方式
      • 公有繼承(public)
      • 受保護(hù)繼承(protected)
      • 私有繼承(private)
    • 繼承關(guān)系中構(gòu)造和析構(gòu)函數(shù)
      • 繼承關(guān)系中構(gòu)造函數(shù)之間的關(guān)系
      • 繼承關(guān)系中析構(gòu)函數(shù)之間的關(guān)系
      • 繼承中構(gòu)造和析構(gòu)函數(shù)的執(zhí)行順序
      • 構(gòu)造和析構(gòu)函數(shù)實例
  • 類的層次(難點)
    • 派生類重定義基類函數(shù)
    • 類指針
      • 類指針的使用
      • 派生類對象到基類對象的轉(zhuǎn)換

基類與派生類

在原有類的基礎(chǔ)上派生出新的類,新類繼承原有類的屬性和方法,稱原有的類為基類, 又稱為父類。由已存在的類派生出的新類稱為派生類,又稱為子類。

假定有一個類A,要創(chuàng)建一個新類B,它是類A的一個特殊版本。類A就稱為基類,類B則稱為派生類。類A是父,類B就是子類。

單繼承和多繼承

一個派生類可以從一個基類派生,也可以從多個基類派生。從一個基類派生的繼承稱為單繼承;從多個基類派生的繼承稱為多繼承。

繼承和派生(難點)

  • 繼承允許以現(xiàn)有的類為基礎(chǔ)來構(gòu)建新類
  • 派生類繼承基類的屬性和行為
  • 派生類可以修改繼承的屬性和行為
  • 派生類可以增加新的屬性和行為
  • 派生類對象也是基類對象
  • 派生類對象和基類對象可以被統(tǒng)一管理


繼承和派生有什么區(qū)別?

繼承與派生其實是同一過程從不同的角度看,我們將保持已有類的特性而構(gòu)造新類的過程稱為繼承,說白了繼承的目的就是實現(xiàn)原來設(shè)計與代碼的重用,希望盡量利用原有的類。然而當(dāng)新的問題出現(xiàn),原有程序無法解決或不能完全解決時,需要對原有程序進(jìn)行改造,在已有類的基礎(chǔ)上新增自己的特性而產(chǎn)生新類的過程稱為派生。

何時使用繼承?

  • 規(guī)則1:如果類A和類B毫不相關(guān),不可以為了使B的功能更多些而讓B繼承A的功能和屬性。
  • 規(guī)則2:若在邏輯上B是A的“一種”,則允許B繼承A的功能和屬性。
  • 規(guī)則3:看起來很簡單,但是實際應(yīng)用時可能會有意外,繼承的概念在程序世界與現(xiàn)實世界并不完全相同。

所以更加嚴(yán)格的繼承規(guī)則應(yīng)當(dāng)是:若在邏輯上B是A的“一種”,并且A的所有功能和屬性對B而言都有意義,只是B類多了一些獨有的特性,則允許B繼承A的功能和屬性。

繼承的意義

  • 便于管理系統(tǒng)中的對象。
  • 系統(tǒng)擴(kuò)充比較容易- 利用程序代碼的再用性。
    -加快程序發(fā)展的速度
    -減少程序的錯誤

派生類的聲明

單繼承派生類的聲明語法為:

class 派生類名 : 繼承方式 基類名 {派生類新增成員的聲明; };

繼承要考慮的部分:①派生類不同于基類的部分;②派生類擴(kuò)充基類的部分。

示例:

class CForm{ public:CForm();~CForm();//其他省略…… }; class CFormMainMenu:public CForm //公有方式繼承 { public:CFormMainMenu();~CFormMainMenu();//其他省略…… };

類成員的訪問權(quán)限(回顧)

在類中,我們是設(shè)計師,public, private, protected三種成員可以訪問。

在對象中,我們是使用者,只有規(guī)定的接口public才可以訪問;protected, private不能訪問。

私有成員(private):可以被類自身的成員和友元訪問,但不能被包括派生類在內(nèi)的其他任何類和任何普通函數(shù)訪問 。

公有成員(public):可以被任何普通函數(shù)和任何類的成員函數(shù)訪問。

保護(hù)成員(protected):可以被類自身的成員和友元訪問外,還可以被派生類的成員函數(shù)訪問,但不能被任何非友元的普通函數(shù)訪問

基類中的私有成員

能被派生類繼承

無論是公有繼承還是私有繼承,都不能被派生類的成員函數(shù)直接訪問

能通過基類的public或protect成員函數(shù)訪問。

實例:

#include<iostream> using namespace std;class A { private :int a; public ://構(gòu)造函數(shù),默認(rèn)將a賦值為2;A(){a = 2;}//獲得私有成員a的值int getNum(){return a;} };class B : private A { public://因為是私有繼承,無法訪問基類的公有成員函數(shù),//只能自定義一個成員函數(shù)來訪問該類B從基類A繼承下來的屬性。int get(){return getNum();//getNum函數(shù)是從基類私有繼承下來的私有函數(shù)。} };int main() {B b;cout<<b.get()<<endl; }執(zhí)行結(jié)果: 2

派生類的三種繼承方式

類中的成員被派生類繼承后成員對外的可見性會有所不同。

  • 公有繼承(public):特點是基類的公有成員和保護(hù)成員作為派生類的成員時,它們都保持原有的狀態(tài),而基類的私有成員仍然是私有的。
  • 受保護(hù)繼承(protected):特點是基類的所有公有成員和保護(hù)成員都成為派生類的保護(hù)成員,并且只能被它的派生類成員函數(shù)或友元訪問,基類的私有成員仍然是私有的。
  • 私有繼承(private):默認(rèn)繼承方式,特點是基類的公有成員和保護(hù)成員都作為派生類的私有成員,并且不能被這個派生類的子類所訪問。

三種繼承方式的區(qū)別:

公有繼承(public)

基類中公有成員和受保護(hù)成員被繼承后可見性不變

public方式繼承成員存取權(quán)限等級的變化

受保護(hù)繼承(protected)

基類中公有成員和受保護(hù)成員被繼承后都是受保護(hù)的。

私有繼承(private)

基類中公有成員和受保護(hù)成員被繼承后都是私有的

private方式繼承成員存取權(quán)限等級的變化

繼承關(guān)系中構(gòu)造和析構(gòu)函數(shù)

繼承關(guān)系中構(gòu)造函數(shù)之間的關(guān)系

派生類不繼承基類的構(gòu)造函數(shù)

派生類和基類的構(gòu)造函數(shù)之間是一種自動調(diào)用的關(guān)系

創(chuàng)建派生類對象時,派生類構(gòu)造函數(shù)要調(diào)用基類的構(gòu)造函數(shù)對基類的數(shù)據(jù)成員進(jìn)行初始化
-先執(zhí)行基類構(gòu)造函數(shù),然后執(zhí)行派生類構(gòu)造函數(shù)體
-基類構(gòu)造函數(shù)需要參數(shù)時需要顯式調(diào)用,格式:

派生類名::派生類名(派生類構(gòu)造參數(shù)表):基類(基類構(gòu)造函數(shù)參數(shù)表)

-基類構(gòu)造函數(shù)不需要參數(shù)時(有默認(rèn)構(gòu)造函數(shù)),隱式調(diào)用

繼承關(guān)系中析構(gòu)函數(shù)之間的關(guān)系

派生類不繼承基類的析構(gòu)函數(shù)

派生類和基類的析構(gòu)函數(shù)之間是一種自動調(diào)用的關(guān)系

派生類的析構(gòu)函數(shù)也需要調(diào)用基類的析構(gòu)函數(shù)做一些和基類相關(guān)的清理工作

銷毀派生類對象時,先執(zhí)行派生類析構(gòu)函數(shù),然后執(zhí)行基類析構(gòu)函數(shù)體

繼承中構(gòu)造和析構(gòu)函數(shù)的執(zhí)行順序

構(gòu)造函數(shù)的執(zhí)行順序:
①先調(diào)用基類的構(gòu)造函數(shù)初始化從基類繼承的數(shù)據(jù)成員
②再執(zhí)行自己的函數(shù)體初始化定義于派生類的數(shù)據(jù)成員

析構(gòu)函數(shù)的執(zhí)行順序:
①派生類的析構(gòu)函數(shù)先執(zhí)行自己的函數(shù)體
②再調(diào)用基類的析構(gòu)函數(shù)

構(gòu)造和析構(gòu)函數(shù)實例

#include<iostream> using namespace std;class People { public:People(char *str); //構(gòu)造函數(shù)~People(); //析構(gòu)函數(shù) protected:char *name; };//構(gòu)造函數(shù)的實現(xiàn) People::People(char *str) {name = new char[strlen(str)+1];strcpy(name, str);cout<<"People construct: "<<name<<endl; } //析構(gòu)函數(shù)的實現(xiàn) People::~People() {cout<<"People destroy: "<<name<<endl;delete []name; }class Teacher : public People { public:Teacher(char *str, char *sch); //構(gòu)造函數(shù)~Teacher(); //析構(gòu)函數(shù) protected:char *school; }; Teacher::Teacher(char *str, char *sch) : People(str) //調(diào)用基類的構(gòu)造函數(shù) { school = new char[strlen(sch)+1];strcpy(school,sch);cout<<"Teacher construct: "<<name<<" in "<<school<<endl; } Teacher::~Teacher() {cout<<"Teacher destroy: "<<name<<" in "<<school<<endl;delete []school; } int main () {People tmp("Zhang San");People p("Li Si");Teacher t("Wang Wu", "FuZhou University");return 0; }執(zhí)行結(jié)果: People construct: Zhang San People construct: Li Si People construct: Wang Wu Teacher construct: Wang Wu in FuZhou University Teacher destroy: Wang Wu in FuZhou University People destroy: Wang Wu People destroy: Li Si People destroy: Zhang San

類的層次(難點)

類的層次:
①一個類可以是某個繼承關(guān)系中的基類,也可以是另一個繼承關(guān)系中的派生類
②類A派生出類B,類B又派生出類C,則類B是類C的直接基類,類A是類C的間接基類

定義派生類時,直接基類要明確列出,間接基類不用列出

例子:

class A { protected:int aMember;// 其他省略...... }; class B: protected A { protected:int bMember;// 其他省略...... }; class C: private B { protected:int cMember; };

派生類重定義基類函數(shù)

在派生類中重定義基類的函數(shù):
①派生類自動繼承基類的所有成員
②重定義函數(shù)的函數(shù)原型和基類中被重定義函數(shù)的函數(shù)原型必須完全相同
③基類與派生類成員函數(shù)同名可能導(dǎo)致基類的成員函數(shù)被隱藏
④重定義之后兩個函數(shù)共存,但調(diào)用方法不同
-調(diào)用基類函數(shù):基類名 + :: + 函數(shù)名
-調(diào)用派生類函數(shù):直接調(diào)用

如果派生類中于出現(xiàn)相同的成員需要編程時注意其存取的范圍。不能運(yùn)用基類的成員函數(shù)來設(shè)定派生類的數(shù)據(jù)成員, 而只能在派生類中重新定義存取數(shù)據(jù)成員的成員函數(shù)。

重定義實例:

#include <iostream> #include <vector> #include <string.h>using namespace std;class CForm { public:CForm(string title,vector<string>& menu);CForm(string title);void Load(); protected:void PrintTitle();void PrintMenu(); private:string m_title;vector<string> m_menu; }; CForm::CForm(string title) {m_title=title; } CForm::CForm(string title,vector<string> &menu) {m_title = title;m_menu = menu; } void CForm::Load() {PrintTitle();PrintMenu(); } void CForm::PrintMenu() {cout<<"menu = ";for(vector<string>::iterator it = m_menu.begin();it!=m_menu.end();it++){cout<<*it<<" ";}cout<<endl; } void CForm::PrintTitle() {cout<<"m_title = "<<m_title<<endl; }//派生類 class CFormMainMenu:public CForm { public:CFormMainMenu(string title,vector<string>& menu,int color);CFormMainMenu(string title,int color);void Load(); protected: private:int m_color; }; void CFormMainMenu::Load() {CForm::Load();//cout<<"m_menu = "<<m_menu<<endl; //錯誤 想獲得基類的m_menu值,只能通過調(diào)用基類的保護(hù)成員函數(shù)或公有成員函數(shù)cout<<"my background color is yellow!"<<endl; } CFormMainMenu::CFormMainMenu(string title,int color):CForm(title) {m_color=color; } CFormMainMenu::CFormMainMenu(string title,vector<string>& menu,int color):CForm(title,menu) {m_color=color; }int main() {vector<string> menu;menu.push_back("you");menu.push_back("are");menu.push_back("my");menu.push_back("son");CFormMainMenu from("Main Menu",menu,12);from.Load();return 0; }執(zhí)行結(jié)果: m_title = Main Menu you are my son my background color is yellow!

類指針

類名也可以用來聲明指針

類的指針可以操作類的對象,也可以操作派生類的對象(派生類對象也是基類對象)

派生類對象和基類對象可以通過指針統(tǒng)一操作和管理

類指針的使用

類指針操作類對象的幾種可能:
①基類指針操作基類對象(自然)
②派生類指針操作派生類對象(自然)
③基類指針操作派生類對象——把派生類對象作為基類對象看(安全)
④派生類指針操作基類對象——把基類對象作為派生類對象看(危險)

派生類對象到基類對象的轉(zhuǎn)換

當(dāng)派生類以Public方式繼承基類時,編譯器可自動執(zhí)行的轉(zhuǎn)換(向上轉(zhuǎn)型 upcasting 安全轉(zhuǎn)換)
①派生類對象自動轉(zhuǎn)換為基類對象(特有的成員消失)
②派生類對象指針自動轉(zhuǎn)化為基類對象指針
③派生類對象引用自動轉(zhuǎn)化為基類對象引用

當(dāng)派生類以private/protected方式繼承基類時
①派生類對象指針(引用)轉(zhuǎn)化為基類對象指針(引用)需用強(qiáng)制類型轉(zhuǎn)化
(基類&)派生類對象
(基類*)派生類對象指針

②基類對象指針(引用)可用強(qiáng)制類型轉(zhuǎn)換為派生類對象指針(引用), 而基類對象無法執(zhí)行這類轉(zhuǎn)換。

向下轉(zhuǎn)型不安全,沒有自動轉(zhuǎn)換的機(jī)制。

可以使用static_cast運(yùn)算符進(jìn)行強(qiáng)制類型轉(zhuǎn)換,但僅限派生類以public方式繼承基類。

實例:

#include <iostream> #include <string.h> using namespace std;//基類People class People { public:People(char *str, int s); //構(gòu)造函數(shù)中參數(shù)s大于0表示男性,否則為女性~People();int getSex();char* getName(); private:char *name;int sex; }; People::People(char *str, int s) {name = new char[strlen(str)+1];strcpy(name, str);if (s>0)sex = 1; //男性elsesex = 0; //女性 } People::~People() {delete []name; } int People::getSex() {return sex; } char * People::getName() {static char str[128];strcpy(str,name);return str; }//派生類Teacher class Teacher : public People { public:Teacher(char *str, int s, char *sch, int y);~Teacher();int getWorkYears();char *getSchool(); private:char *school;int years; }; Teacher::Teacher(char *str,int s,char *sch,int y):People(str, s) { //調(diào)用基類的構(gòu)造函數(shù)school = new char[strlen(sch)+1];strcpy(school,sch);years = (y>0) ? y : 0; } Teacher::~Teacher() {delete []school; } int Teacher::getWorkYears() {return years; } char * Teacher::getSchool() {static char str[1024];strcpy(str,school);return str; }int main() {People p("Zhang San", 1), *pptr;Teacher t("Li Si",0,"Wuhan University",20), *tptr;pptr = &p;//用基類指針指向基類對象cout<< "People p: " << pptr->getName()<<", "<<(pptr->getSex()?"male":"female")<<endl;pptr=&t;//用基類指針指向派生類對象cout<<"Teacher t: "<<pptr->getName()<<","<<(pptr->getSex()?"male":"female")<<endl;//要調(diào)用定義于派生類中的函數(shù)必須進(jìn)行類型的強(qiáng)制轉(zhuǎn)換cout<<"\tin "<<((Teacher*)pptr)->getSchool()<<"for "<<((Teacher*)pptr)->getWorkYears()<<" years."<<endl;tptr = (Teacher*)&p; //用派生類指針指向基類對象cout<<"People p: "<<tptr->getName()<<", "<<(tptr->getSex()?"male":"female")<<endl;//危險,訪問了不存在的屬性cout<<"\tin(危險,訪問了不存在的屬性) "<<tptr->getSchool()<<" for "<< tptr->getWorkYears()<<" years."<<endl;tptr = &t; //用派生類指針指向派生類對象//調(diào)用基類中定義的函數(shù)cout<<"People p: "<<tptr->getName()<<", "<<(tptr->getSex()?"male":"female")<<endl;cout<<"\tin "<<tptr->getSchool()<<" for "<<tptr->getWorkYears()<<" years."<<endl;return 0; }執(zhí)行結(jié)果: People p: Zhang San, male Teacher t: Li Si,femalein Wuhan Universityfor 20 years. People p: Zhang San, malein(危險,訪問了不存在的屬性) # for 9699072 years. People p: Li Si, femalein Wuhan University for 20 years.

總結(jié)

以上是生活随笔為你收集整理的复习笔记(四)——C++继承的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。