《c++繼承與派生》課件_第1頁
《c++繼承與派生》課件_第2頁
《c++繼承與派生》課件_第3頁
《c++繼承與派生》課件_第4頁
《c++繼承與派生》課件_第5頁
已閱讀5頁,還剩40頁未讀 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

C++繼承與派生本課件將深入講解C++中的繼承與派生,涵蓋基本概念、不同繼承方式、虛函數和虛基類、構造和析構函數、靜態(tài)成員、訪問控制、類型轉換以及繼承的應用場景等內容。C++中的繼承代碼復用繼承是一種面向對象編程的重要機制,它允許我們創(chuàng)建新的類(派生類)并繼承已有類的屬性和方法(基類),從而實現(xiàn)代碼復用,減少冗余代碼。代碼擴展繼承可以用來擴展現(xiàn)有類的功能,派生類可以添加新的屬性和方法,從而實現(xiàn)對基類功能的擴展。多態(tài)實現(xiàn)繼承是多態(tài)實現(xiàn)的基礎,通過虛函數和抽象類,我們可以實現(xiàn)不同類型的對象執(zhí)行同一方法的不同行為,提高代碼的可擴展性和靈活性。繼承的概念和特點繼承是面向對象編程中的一種機制,它允許一個類(派生類)繼承另一個類(基類)的屬性和方法。派生類可以訪問基類的所有公共成員和受保護成員,但不能直接訪問基類的私有成員。繼承關系是一種“is-a”關系,例如,汽車“is-a”交通工具?;惻c派生類基類基類是被繼承的類,也稱為父類或超類。它定義了派生類所繼承的屬性和方法。派生類派生類是繼承自基類的類,也稱為子類或派生類。它可以繼承基類的屬性和方法,并添加新的屬性和方法。繼承的形式1公有繼承(public):派生類繼承基類的所有公共成員和受保護成員,并將其作為自己的公共成員。2保護繼承(protected):派生類繼承基類的所有公共成員和受保護成員,并將其作為自己的受保護成員。3私有繼承(private):派生類繼承基類的所有公共成員和受保護成員,并將其作為自己的私有成員。公有繼承代碼示例classAnimal{public:voidmove(){cout<<"動物正在移動"<<endl;}};classDog:publicAnimal{public:voidbark(){cout<<"狗在叫"<<endl;}};繼承特點在公有繼承中,派生類可以訪問基類的所有公共成員和受保護成員,并將其作為自己的公共成員。這意味著派生類的對象可以像使用基類對象一樣使用繼承的成員。保護繼承代碼示例classAnimal{protected:intage;public:voidsetAge(inta){age=a;}intgetAge(){returnage;}};classDog:protectedAnimal{public:voidbark(){cout<<"狗在叫"<<endl;}};繼承特點保護繼承允許派生類訪問基類的所有公共成員和受保護成員,但將其作為自己的受保護成員。這意味著派生類可以訪問這些成員,但其子類只能通過派生類來訪問它們。私有繼承代碼示例classAnimal{private:intage;public:voidsetAge(inta){age=a;}intgetAge(){returnage;}};classDog:privateAnimal{public:voidbark(){cout<<"狗在叫"<<endl;}};繼承特點私有繼承將基類的所有公共成員和受保護成員都作為派生類的私有成員。這意味著派生類可以訪問這些成員,但其子類和外部代碼都不能直接訪問。多重繼承代碼示例classA{public:voidmethodA(){cout<<"A類的方法"<<endl;}};classB{public:voidmethodB(){cout<<"B類的方法"<<endl;}};classC:publicA,publicB{public:voidmethodC(){cout<<"C類的方法"<<endl;}};繼承特點多重繼承允許一個派生類繼承多個基類。派生類可以繼承所有基類的公共成員和受保護成員,但需要明確指定繼承方式,例如公有繼承、保護繼承或私有繼承。虛函數和虛基類1虛函數是指在基類中聲明為virtual的函數,它允許在派生類中重寫基類中的函數,從而實現(xiàn)多態(tài)性。2虛基類是指在繼承關系中被多個派生類共享的基類,它確保派生類的對象只包含基類的一個副本,而不是多個副本。虛函數的實現(xiàn)代碼示例classAnimal{public:virtualvoidmakeSound(){cout<<"動物在叫"<<endl;}};classDog:publicAnimal{public:voidmakeSound()override{cout<<"狗在叫"<<endl;}};classCat:publicAnimal{public:voidmakeSound()override{cout<<"貓在叫"<<endl;}};實現(xiàn)機制虛函數的實現(xiàn)利用虛函數表(vtable)來實現(xiàn)。每個類都有一個虛函數表,其中存儲了該類的所有虛函數的地址。派生類重寫虛函數后,會更新自己的虛函數表,指向新實現(xiàn)的函數地址。虛函數與多態(tài)代碼示例Animal*animal=newDog();animal->makeSound();//輸出:狗在叫animal=newCat();animal->makeSound();//輸出:貓在叫多態(tài)實現(xiàn)通過虛函數,我們可以使用基類指針指向不同類型的派生類對象,并調用相同的方法,但執(zhí)行不同的行為。這就是多態(tài)性的體現(xiàn),它允許我們用統(tǒng)一的方式處理不同類型的對象。純虛函數與抽象類代碼示例classShape{public:virtualdoublegetArea()=0;//純虛函數};classCircle:publicShape{public:doublegetArea()override{return3.14159*radius*radius;}private:doubleradius;};概念解釋純虛函數是虛函數,但沒有函數體。抽象類是指包含至少一個純虛函數的類。抽象類不能直接實例化,只能作為基類被繼承,用于定義接口,強制派生類實現(xiàn)純虛函數。抽象類的使用代碼示例Shape*shape=newCircle(5);//創(chuàng)建一個圓形對象cout<<shape->getArea()<<endl;//輸出:78.5397應用場景抽象類主要用于定義接口,強制派生類實現(xiàn)特定的方法,例如在圖形系統(tǒng)中,使用Shape類來定義圖形的接口,不同的圖形類(圓形、矩形等)需要實現(xiàn)getArea()方法來計算面積。構造函數與析構函數構造函數構造函數是在創(chuàng)建對象時自動調用的函數,用于初始化對象的成員變量。它與類同名,沒有返回值類型。析構函數析構函數是在對象銷毀時自動調用的函數,用于釋放對象占用的資源。它以“~”開頭,后面跟類名,沒有返回值類型。構造函數的繼承代碼示例classAnimal{public:Animal(stringname):name(name){cout<<"Animal構造函數"<<endl;}private:stringname;};classDog:publicAnimal{public:Dog(stringname,intage):Animal(name),age(age){cout<<"Dog構造函數"<<endl;}private:intage;};繼承特點派生類的構造函數必須先調用基類的構造函數來初始化基類成員,可以使用初始化列表來實現(xiàn)。初始化列表中的基類構造函數調用必須放在派生類構造函數參數列表之后。析構函數的繼承代碼示例classAnimal{public:Animal(stringname):name(name){cout<<"Animal構造函數"<<endl;}~Animal(){cout<<"Animal析構函數"<<endl;}private:stringname;};classDog:publicAnimal{public:Dog(stringname,intage):Animal(name),age(age){cout<<"Dog構造函數"<<endl;}~Dog(){cout<<"Dog析構函數"<<endl;}private:intage;};繼承特點派生類的析構函數會在對象銷毀時自動調用,它會先調用基類的析構函數來釋放基類成員占用的資源,然后釋放派生類成員占用的資源。虛析構函數代碼示例classAnimal{public:virtual~Animal(){cout<<"Animal析構函數"<<endl;}};classDog:publicAnimal{public:~Dog(){cout<<"Dog析構函數"<<endl;}};應用場景當使用基類指針指向派生類對象時,如果基類的析構函數不是虛函數,那么在釋放基類指針時,只有基類的析構函數會被調用,派生類的析構函數不會被調用,導致內存泄漏。為了避免這種情況,需要將基類的析構函數聲明為虛函數。利用初始化列表代碼示例classAnimal{public:Animal(stringname):name(name){}private:stringname;};classDog:publicAnimal{public:Dog(stringname,intage):Animal(name),age(age){}private:intage;};使用建議在派生類的構造函數中,使用初始化列表來初始化成員變量是一種良好的編程習慣,因為它可以提高代碼的可讀性和效率。例如,在上面的代碼中,我們使用初始化列表來初始化基類Animal中的name成員變量和派生類Dog中的age成員變量。繼承中的靜態(tài)成員代碼示例classAnimal{public:staticintcount;};intAnimal::count=0;//靜態(tài)成員初始化classDog:publicAnimal{public:voidbark(){cout<<"狗在叫"<<endl;}};繼承特點靜態(tài)成員屬于類,而不是對象,每個類只有一個靜態(tài)成員的副本。派生類可以繼承基類的靜態(tài)成員,但不能修改基類的靜態(tài)成員。在派生類中,可以使用基類名和作用域運算符來訪問基類的靜態(tài)成員。繼承中的靜態(tài)成員函數代碼示例classAnimal{public:staticvoidprintCount(){cout<<"動物數量:"<<count<<endl;}private:staticintcount;};intAnimal::count=0;classDog:publicAnimal{public:voidbark(){cout<<"狗在叫"<<endl;}};繼承特點靜態(tài)成員函數屬于類,而不是對象,它可以通過類名和作用域運算符來調用。派生類可以繼承基類的靜態(tài)成員函數,并可以直接調用它們。訪問控制與繼承代碼示例classA{private:inta;protected:intb;public:intc;};classB:publicA{public:voidprintB(){cout<<b<<endl;//可以訪問保護成員b}};訪問控制在繼承中,派生類對基類成員的訪問權限取決于基類成員的訪問控制和繼承方式。例如,在公有繼承中,派生類可以訪問基類的公共成員和受保護成員,但不能訪問基類的私有成員。保護成員的特點1保護成員是基類中聲明為protected的成員變量和方法。它們只能被基類本身和其派生類訪問。2保護成員通常用于定義基類內部需要被派生類訪問但不想被外部代碼訪問的成員。保護成員的繼承代碼示例classAnimal{protected:stringname;public:Animal(stringname):name(name){}};classDog:publicAnimal{public:voidprintName(){cout<<name<<endl;//可以訪問保護成員name}};繼承特點在保護繼承中,派生類將繼承基類的保護成員,并將其作為自己的保護成員。這意味著派生類可以訪問這些成員,但其子類只能通過派生類來訪問它們。類型轉換與繼承1動態(tài)類型轉換:在運行時根據對象的實際類型進行類型轉換,使用dynamic_cast運算符。2靜態(tài)類型轉換:在編譯時根據變量的聲明類型進行類型轉換,使用static_cast運算符。動態(tài)類型轉換代碼示例classAnimal{public:virtualvoidmakeSound(){cout<<"動物在叫"<<endl;}};classDog:publicAnimal{public:voidmakeSound()override{cout<<"狗在叫"<<endl;}};Animal*animal=newDog();Dog*dog=dynamic_cast(animal);if(dog!=nullptr){dog->bark();//只有當animal指向Dog對象時,才能調用bark()方法}else{cout<<"animal不是Dog類型的對象"<<endl;}應用場景動態(tài)類型轉換主要用于在運行時根據對象的實際類型執(zhí)行不同的操作。例如,在圖形系統(tǒng)中,使用dynamic_cast來判斷一個圖形對象是否是圓形,如果是,則調用其計算面積的方法。靜態(tài)類型轉換代碼示例classAnimal{public:Animal(stringname):name(name){}private:stringname;};classDog:publicAnimal{public:Dog(stringname,intage):Animal(name),age(age){}private:intage;};Dog*dog=newDog("旺財",3);Animal*animal=static_cast(dog);//將Dog對象轉換為Animal對象應用場景靜態(tài)類型轉換主要用于在編譯時進行類型轉換,它是一種安全的類型轉換,不會導致運行時錯誤。例如,將派生類對象轉換為基類對象時,可以使用static_cast運算符。常量對象與繼承代碼示例classAnimal{public:Animal(stringname):name(name){}voidprintName()const{cout<<name<<endl;}private:stringname;};constAnimalanimal("小貓");//創(chuàng)建一個常量Animal對象animal.printName();//可以調用常量成員函數繼承特點常量對象不能修改其成員變量的值。常量成員函數是指聲明為const的成員函數,它不能修改對象的狀態(tài)。常量對象只能調用常量成員函數,以確保其狀態(tài)不會被改變。常量成員函數代碼示例classAnimal{public:Animal(stringname):name(name){}voidprintName()const{cout<<name<<endl;}private:stringname;};使用建議如果一個成員函數不修改對象的狀態(tài),那么應該將其聲明為const成員函數,這樣可以提高代碼的可讀性和安全性。例如,在上面的代碼中,printName()函數只輸出對象的name成員變量的值,它不修改對象的狀態(tài),因此應該將其聲明為const成員函數。常量對象的初始化代碼示例classAnimal{public:Animal(stringname):name(name){}private:stringname;};constAnimalanimal("小貓");//創(chuàng)建一個常量Animal對象初始化方法常量對象必須在聲明時進行初始化,并且初始化值必須是常量表達式,例如字面量或常量變量。常量對象不能在構造函數中進行初始化。常量引用代碼示例constAnimalanimal("小貓");constAnimal&ref=animal;//創(chuàng)建一個常量引用應用場景常量引用可以用來引用常量對象,它可以保證引用的對象不會被修改。常量引用可以提高代碼的效率和安全性。友元與繼承代碼示例classAnimal{private:stringname;friendclassDog;//聲明Dog類為Animal類的友元類};classDog{public:voidprintName(Animal&animal){cout<<<<endl;//可以訪問Animal類的私有成員name}};繼承特點友元關系不具有傳遞性,也就是說,如果A類是B類的友元,而B類是C類的友元,那么A類并不一定是C類的友元。友元關系是用來打破類的封裝性,在某些情況下可以提高代碼的效率或靈活性。友元函數的調用代碼示例Animalanimal("小貓");Dogdog;dog.printName(animal);//通過Dog類的友元函數訪問Animal類的私有成員調用方式友元函數可以通過友元關系訪問類的私有成員和保護成員。友元函數可以通過對象名和作用域運算符來調用,也可以通過友元類的對象來調用。友元類的定義代碼示例classAnimal{private:stringname;friendclassDog;//聲明Dog類為Animal類的友元類};classDog{public:voidprintName(Animal&animal){cout<<<<endl;//可以訪問Animal類的私有成員name}};定義方法友元類可以通過在友元類的聲明中使用friend關鍵字來定義。友元類可以訪問友元類的所有成員,包括私有成員和保護成員。繼承與公有成員訪問代碼示例classAnimal{public:Animal(stringname):name(name){}voidprintName(){cout<<name<<endl;}private:stringname;};classDog:publicAnimal{public:Dog(stringname,intage):Animal(name),age(age){}voidbark(){cout<<"狗在叫"<<endl;}private:intage;};Dogdog("旺財",3);dog.printName();//可以訪問基類的公有成員printName()訪問特點在公有繼承中,派生類可以訪問基類的所有公有成員和受保護成員,并將其作為自己的公有成員。這意味著派生類可以像使用基類對象一樣使用繼承的成員。繼承與保護成員訪問代碼示例classAnimal{protected:stringname;public:Animal(stringname):name(name){}};classDog:publicAnimal{public:Dog(stringname,intage):Animal(name),age(age){}voidprintName(){cout<<name<<endl;//可以訪問基類的保護成員name}private:intage;};Dogdog("旺財",3);dog.printName();//可以訪問基類的保護成員name訪問特點在公有繼承中,派生類可以訪問基類的所有公有成員和受保護成員。這意味著派生類可以像使用基類對象一樣使用繼承的成員。繼承與私有成員訪問代碼示例classAnimal{private:stringname;public:Animal(stringname):name(name){}};classDog:publicAnimal{public:Dog(stringname,intage):Animal(name),age(age){}private:intage;};Dogdog("旺財",3);//="小黑";//錯誤:不能訪問基類的私有成員name訪問特點在所有繼承方式中,派生類都不能直接訪問基類的私有成員。這是因為私有成員是基類內部的私有數據,它們只能被基類本身訪問,不能被任何其他類訪問,包括派生類。繼承的應用場景圖形系統(tǒng)使用基類Shape來定義圖形的接口,不同的

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論