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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

c++ 多态 运行时多态和编译时多态_C++核心编程 第十一节 多态

發布時間:2024/7/23 c/c++ 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++ 多态 运行时多态和编译时多态_C++核心编程 第十一节 多态 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言:多態是C++面向對象三大特性之一。

多態,指的是一個類實例的相同方法在不同情形有不同表現形式。具有不同內部結構的對象可以共享外部接口。C++多態就是用一個更通用的基類指針指向不同的子類實例,為了能調用正確的方法,我們需要用到虛函數和虛繼承。

#include using namespace std;class Animal{public: // Speak函數就是虛函數 // 函數前面加上 virtual 關鍵字變成虛函數,那么編譯器在編譯的時候就不能確定函數的調用了 virtual void speak(){ cout << "動物在說話" << endl; }};class Cat : public Animal{public: void speak(){ cout << "小貓在說話" << endl; }};class Dog : public Animal{public: void speak(){ cout << "小狗在說話" << endl; }};// 希望傳入什么對象,那么就調用什么對象的函數// 如果函數地址在編譯階段就能確定,那么靜態聯編// 如果函數地址在運行階段才能確定,就是動態聯編void DoSpeak(Animal & animal){ animal.speak(); }// 多態滿足條件:// 1、有繼承關系// 2、子類重寫父類中的虛函數// 多態使用:// 父類指針或引用指向子類對象void test(){ Cat cat; DoSpeak(cat); Dog dog; DoSpeak(dog);}int main(){ test(); return 0;}

多態案例——計算器類

案例描述:分別利用普通寫法和多態技術,設計實現兩個操作數進行運算的計算器類。

#include#includeusing namespace std;class Calculator{public: int getResult(string oper){ if(oper == "+"){ return m_Num1 + m_Num2; } else if(oper == "-"){ return m_Num1 - m_Num2; } else if (oper == "*"){ return m_Num1 * m_Num2; } // 如果要提供新的運算,需要修改源碼 } int m_Num1; int m_Num2;};void test(){ // 普通實現測試 Calculator c; c.m_Num1 = 10; c.m_Num2 = 20; cout << c.m_Num1 << " + " << c.m_Num2 << " = " << c.m_Num1 + c.m_Num2 << endl; cout << c.m_Num1 << " - " << c.m_Num2 << " = " << c.m_Num1 - c.m_Num2 << endl; cout << c.m_Num1 << " * " << c.m_Num2 << " = " << c.m_Num1 * c.m_Num2 << endl;}// 多態實現// 抽象計算器類// 多態優點:代碼組織結構清晰,可讀性強,利于前期和后期的擴展以及維護class AbstractCalculator{public: virtual int getResult(){ return 0;} int m_Num1; int m_Num2;};// 加法計算器class AddCalculator : public AbstractCalculator{public: int getResult(){ return m_Num1 + m_Num2; }};// 減法計算器class SubCalculator : public AbstractCalculator{public: int getResult(){ return m_Num1 - m_Num2; }};// 乘法計算器class MulCalculator : public AbstractCalculator{public: int getResult(){ return m_Num1 * m_Num2; }};void test2(){ // 創建加法計算器 AbstractCalculator *abc = new AddCalculator; abc->m_Num1 = 10; abc->m_Num2 = 20; cout << abc->m_Num1 << " + " << abc->m_Num2 << " = " << abc->getResult() << endl; delete abc; // 用完了銷毀 // 創建減法計算器 abc = new SubCalculator; abc->m_Num1 = 10; abc->m_Num2 = 20; cout << abc->m_Num1 << " - " << abc->m_Num2 << " = " << abc->getResult() << endl; delete abc; // 創建乘法計算器 abc = new MulCalculator; abc->m_Num1 = 10; abc->m_Num2 = 20; cout << abc->m_Num1 << " * " << abc->m_Num2 << " = " << abc->getResult() << endl; delete abc;}int main(){ test(); test2(); return 0;}

總結:C++開發提倡利用多態設計程序架構,因為多態優點很多。

純虛函數和抽象類

在多態中,通常父類中虛函數的實現沒有意義,主要都是調用子類重寫的內容。因此可以將虛函數改為純虛函數。

#includeusing namespace std;class Base{public: // 純虛函數 // 類中只要有一個純虛函數就稱為抽象類 // 抽象類無法實例化對象 // 子類必須重寫父類中的純虛函數,否則也屬于抽象類 virtual void func() = 0;};class Son : public Base{public: virtual void func(){ cout << "func調用" << endl; }};void test(){ Base * base = NULL;// base = new Base; // 抽象類無法實例化對象 base = new Son; base->func(); delete base;}int main(){ test(); return 0;}

多態案例二—制作飲品

案例描述:制作飲品的大致流程為:煮水 - 沖泡 - 倒入杯中 - 加入輔料

利用多態技術實現本案例,提供抽象制作飲品基類,提供子類制作茶水和咖啡。

#includeusing namespace std;class AbstractDringking{public: // 燒水 virtual void Boil() = 0; // 沖泡 virtual void Brew() = 0; // 倒入杯中 virtual void PourInCup() = 0; // 加入輔料 virtual void PutSomething() = 0; // 規定流程 void MakeDrink(){ Boil(); Brew(); PourInCup(); PutSomething(); }};// 制作茶水class Tea : public AbstractDringking{public: void Boil(){ cout << "煮農夫山泉" << endl; } void Brew(){ cout << "沖泡茶葉" << endl; } void PourInCup(){ cout << "將茶水倒入杯中" << endl; } void PutSomething(){ cout << "加入枸杞" << endl; }};// 制作咖啡class Coffee : public AbstractDringking{public: void Boil(){ cout << "煮純凈水" << endl; } void Brew(){ cout << "沖泡咖啡" << endl; } void PourInCup(){ cout << "將咖啡倒入杯中" << endl; } void PutSomething(){ cout << "加入牛奶" << endl; }};// 業務函數void Dowork(AbstractDringking* drink){ drink->MakeDrink(); delete drink;}void test(){ Dowork(new Tea); cout << "----------------------" << endl; Dowork(new Coffee);}int main(){ test(); return 0;}

虛析構和純虛析構

多態使用時,如果子類中有屬性開辟到堆區,那么父類指針在釋放時無法調用到子類的析構代碼。

解決方式:將父類中的析構函數改為虛析構或者純虛析構。

#includeusing namespace std;class Animal{public: Animal(){ cout << "Animal構造函數" << endl; } virtual void Speak() = 0; // 析構函數加上virtual關鍵字,變成虛析構函數// virtual ~Animal(){// cout << "Animal虛析構函數" << endl;// } virtual ~Animal() = 0;};Animal::~Animal() { cout << "Animal 純虛析構函數" << endl; }// 和包含普通純虛函數的類一樣,包含類普通純虛析構函數的類也是一個抽象類。不能夠被實例化。class Cat : public Animal{public: Cat(string name){ cout << "Cat構造函數" << endl; m_Name = new string(name); } virtual void Speak(){ cout << *m_Name << "小貓在說話" << endl; } ~Cat(){ cout << "Cat析構函數" << endl; if(this->m_Name != NULL) delete m_Name; m_Name = NULL; } string *m_Name;};void test(){ Animal *animal = new Cat("Tom"); animal->Speak(); // 通過父類指針去釋放,會導致子類對象可能清理不干凈,造成內存泄露 // 怎么解決?給基類增加一個虛析構函數 // 虛析構函數就是用來解決父類指針釋放子類對象 delete animal;}int main(){ test(); return 0;}

總結:

1、虛析構或純虛析構就是用來解決通過父類指針釋放子類對象

2、如果子類中沒有堆區數據,可以不寫為虛析構或純虛析構

3、擁有純虛析構函數的類也屬于抽象類

多態案例三 - 電腦組裝

案例描述:電腦主要組成部件為CPU(用于計算),顯卡(用于顯示),內存條(用于存儲)

將每個零件封裝出抽象基類,并且提供不同的廠商生產不同的零件,例如Intel廠商和Lenovo廠商。

創建電腦類提供讓電腦工作的函數,并且調用每個零件工作的接口。

#includeusing namespace std;// 抽象CPU類class CPU{public: // 抽象的計算函數 virtual void calculate() = 0;};// 抽象顯卡類class VideoCard{public: virtual void display() = 0;};// 抽象內存條類class Memory{public: virtual void storage() = 0;};class Computer{public: Computer(CPU * cpu, VideoCard * vc, Memory * men){ m_cpu = cpu; m_vc = vc; m_men = men; } // 提供工作的函數 void work(){ // 讓零件工作起來,調用接口 m_cpu->calculate(); m_vc->display(); m_men->storage(); } // 提供析構函數,釋放三個電腦零件 ~Computer(){ if(m_cpu != NULL){ delete m_cpu; m_cpu = NULL; } if(m_vc != NULL){ delete m_vc; m_vc = NULL; } if(m_men != NULL){ delete m_men; m_men = NULL; } }private: CPU * m_cpu; VideoCard * m_vc; Memory * m_men;};// 具體廠商// Intel廠商class IntelCPU : public CPU{public: virtual void calculate(){ cout << "Intel的CPU開始計算" << endl; }};class IntelVideoCard : public VideoCard{public: virtual void display(){ cout << "Intel的顯卡開始顯示了" << endl; }};class IntelMemory : public Memory{public: virtual void storage() { cout << "Intel的內存條開始存儲了" << endl; }};// Lenovo廠商class LenovoCPU : public CPU{public: virtual void calculate(){ cout << "Lenovo的CPU開始計算" << endl; }};class LenovoVideoCard : public VideoCard{public: virtual void display(){ cout << "Lenovo的顯卡開始顯示了" << endl; }};class LenovoMemory : public Memory{public: virtual void storage(){ cout << "Lenovo的內存條開始存儲了" << endl; }};void test(){ // 第一條電腦零件 CPU * intelCpu = new IntelCPU; VideoCard * intelCard = new IntelVideoCard; Memory * intelMem = new IntelMemory; cout << "Intel零件組裝電腦開始工作:" << endl; // 創建第一臺電腦 Computer * computer1 = new Computer(intelCpu, intelCard, intelMem); computer1->work(); delete computer1; cout << "------------------------" << endl; cout << "Lenovo零件組裝電腦開始工作:" << endl; // 組裝第二臺電腦 Computer * computer2 = new Computer(new LenovoCPU, new LenovoVideoCard, new LenovoMemory); computer2->work(); delete computer2; cout << "------------------------" << endl; cout << "混裝零件電腦開始工作:" << endl; Computer * computer3 = new Computer(new LenovoCPU, new IntelVideoCard, new LenovoMemory); computer3->work(); delete computer3;}int main(){ test(); return 0;}

????????????????????? ? - END -

總結

以上是生活随笔為你收集整理的c++ 多态 运行时多态和编译时多态_C++核心编程 第十一节 多态的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。