公司設(shè)計(jì)資質(zhì)seo搜索引擎優(yōu)化推廣
1.虛函數(shù)(Virtual Function)
在c++ 中, 虛函數(shù)是定義在基類(lèi)中的函數(shù),但是它可以在派生類(lèi)中進(jìn)行重寫(xiě)(Override) 。
通過(guò)在基類(lèi)中通過(guò)virtual 關(guān)鍵字聲明函數(shù) , 你創(chuàng)建了一個(gè)可以在任何派生類(lèi)中特別實(shí)現(xiàn)的接口。 當(dāng)你有一個(gè)指針指向基類(lèi)或者引用, 并通過(guò)這個(gè)指針或者引用調(diào)用虛函數(shù)時(shí), c++ 運(yùn)行時(shí)會(huì)根據(jù)指針或者引用 實(shí)際指向的對(duì)象來(lái)調(diào)用適當(dāng)?shù)暮瘮?shù)。 這個(gè)過(guò)程是在運(yùn)行時(shí)動(dòng)態(tài)發(fā)生的, 這也就是所謂的動(dòng)態(tài)綁定或晚綁定 。
2.多態(tài)(Polymorphism)
多態(tài)是一個(gè)通用的概念 , 指的是可以通過(guò)同一個(gè)接口訪問(wèn)不同類(lèi)型對(duì)象的能力 。
在c++ 中 多態(tài)通常通過(guò)虛函數(shù)來(lái)實(shí)現(xiàn), 當(dāng)你使用基類(lèi)的指針或者引用調(diào)用一個(gè)虛函數(shù)時(shí), 實(shí)際上會(huì)執(zhí)行派生類(lèi)版本的函數(shù), 這取決于指針或者引用實(shí)際指向的對(duì)象類(lèi)型, 多態(tài)允許你編寫(xiě)通用的代碼, 這些代碼可以與任何從基類(lèi)派生的類(lèi)的對(duì)象一起工作, 而無(wú)需在編譯時(shí)知道確切的派生類(lèi)型 。
3. 例子
上面的不太好理解 : 舉個(gè)簡(jiǎn)單的例子, 有一天你到餐廳吃飯,服務(wù)員給你一張菜單(基類(lèi))進(jìn)行點(diǎn)菜,菜單上有各種食物(派生類(lèi)) , 但你只需要看菜單就可以做出選擇,而不需要知道每種食物是如何準(zhǔn)備的
在c++ 中多態(tài)就相當(dāng)于這個(gè)菜單 , 它允許你使用一個(gè)**通用的接口(基類(lèi)的指針或引用)**來(lái)執(zhí)行可能有多種不同實(shí)現(xiàn)的操作,這意味著我們?cè)趯?xiě)代碼的時(shí)候不必對(duì)象的確切類(lèi)型, 只需要知道它能干什么 。
其中,虛函數(shù)就相當(dāng)于菜單上的各種食物, 我們可以在基類(lèi)中聲明(virtual), 并且在派生類(lèi)中重新定義(override)
3.1 代碼實(shí)現(xiàn)
#include <iostream>
class Food {
public: virtual void prepare(){std::cout << "prepare some food " << std::endl;}
};
class noodele :public Food {
public:void prepare () override {std::cout << "this is your noodel " << std::endl;}
};
class water :public Food {
public:void prepare() override {std::cout << "this is your water " << std::endl;}
};void eat(Food* food)
{ //接口要是 : 基類(lèi)的指針或者引用food->prepare(); //實(shí)現(xiàn)多態(tài)
}
int main()
{Food* myfood = new water();eat(myfood); delete myfood;
}
4.注意
虛函數(shù)雖然非常好用, 但是在使用虛函數(shù)的時(shí)候,并不是所有函數(shù)都得定義成虛函數(shù),因?yàn)閷?shí)現(xiàn)虛函數(shù)是有代價(jià)的,需要注意以下幾方面的:
- **虛析構(gòu)函數(shù):**如果你的類(lèi)有虛函數(shù),也應(yīng)該提供一個(gè)虛析構(gòu)函數(shù),為了確保通過(guò)基類(lèi)指針刪除派生類(lèi)的對(duì)象的時(shí)候,能夠調(diào)用正確的析構(gòu)函數(shù)
- 內(nèi)存和性能考慮 : 使用虛函數(shù)會(huì)增加每個(gè)對(duì)象的內(nèi)存開(kāi)銷(xiāo),以此每個(gè)對(duì)象需要一個(gè)額外的指針來(lái)訪問(wèn)虛函數(shù)表(v-table) ,此外,虛函數(shù)的調(diào)用比非虛函數(shù)慢,因?yàn)樾枰~外的間接尋址
- 虛函數(shù)的繼承: 一旦在基類(lèi)中定義了虛函數(shù),它在派生類(lèi)中自動(dòng)成為虛函數(shù), 即便沒(méi)有 virtual 關(guān)鍵字
5. 靜態(tài)多態(tài)和動(dòng)態(tài)多態(tài)
- 靜態(tài)多態(tài)中, 所有的類(lèi)型檢查和函數(shù)調(diào)用解析都是在編譯時(shí)完成的,一次靜態(tài)多態(tài)不會(huì)引入運(yùn)行時(shí)的開(kāi)銷(xiāo)
- 動(dòng)態(tài)多態(tài) :動(dòng)態(tài)動(dòng)態(tài)主要是運(yùn)行時(shí)進(jìn)行的 主要通過(guò)虛函數(shù)實(shí)現(xiàn)的 ,在動(dòng)態(tài)多態(tài)中, 函數(shù)的調(diào)用不是在編譯時(shí)解析的,而是在運(yùn)行時(shí),當(dāng)你通過(guò)基類(lèi)的指針或者引用在調(diào)用一個(gè)虛函數(shù)時(shí), c++ 運(yùn)行時(shí)會(huì)根據(jù)對(duì)象的實(shí)際類(lèi)型來(lái)確定調(diào)用那個(gè)函數(shù) 。
5.1 函數(shù)重載和模板
- 函數(shù)重載就是指你寫(xiě)了多個(gè)重名的函數(shù),但是傳入的參數(shù)類(lèi)型或者個(gè)數(shù)不一樣,編譯器會(huì)根據(jù)你傳入的參數(shù)類(lèi)型或者參數(shù)個(gè)數(shù)來(lái)決定調(diào)用那個(gè)函數(shù) 。
- 模板就是一種能夠讓你的函數(shù)或者類(lèi)能夠處理不同數(shù)據(jù)類(lèi)型的方法, 你寫(xiě)一次代碼,編譯器會(huì)根據(jù)你使用的具體類(lèi)型來(lái)生成多個(gè)代碼版本
就比如說(shuō)使用模板實(shí)現(xiàn)不同類(lèi)型的數(shù)據(jù)交換
#include <iostream>template <typename T>
void swap(T& a, T& b) {T temp = a;a = b;b = temp;
}int main() {int i = 1, j = 2;swap(i, j); // 交換兩個(gè)intstd::cout << "i: " << i << ", j: " << j << std::endl;double x = 3.14, y = 1.59;swap(x, y); // 交換兩個(gè)doublestd::cout << "x: " << x << ", y: " << y << std::endl;return 0;
}
5.2總結(jié)也就是:
靜態(tài)多態(tài)的類(lèi)型早已知曉 , 多態(tài)性在編譯時(shí)通過(guò)函數(shù)重載和模板實(shí)現(xiàn),沒(méi)有運(yùn)行開(kāi)銷(xiāo)
動(dòng)態(tài)多態(tài)它的類(lèi)型可能未知, 多態(tài)性在運(yùn)行時(shí)通過(guò)虛函數(shù)實(shí)現(xiàn),這涉及到類(lèi)型識(shí)別,有一定的性能開(kāi)銷(xiāo)
6. 什么函數(shù)不能聲明為虛函數(shù)
- 普通函數(shù) : 普通函數(shù)只能被overload, 不能被override,聲明為虛函數(shù)也沒(méi)有意義,因此編譯器會(huì)在編譯時(shí)綁定函數(shù)
- 構(gòu)造函數(shù): 構(gòu)造函數(shù)是為了明確初始化對(duì)象成員才產(chǎn)生的, 然而virtual function 主要是為了再不完全了解細(xì)節(jié)的情況下也能處理對(duì)象, 另外virtual function 函數(shù)是在不同類(lèi)型的對(duì)象產(chǎn)生不同的對(duì)象, 現(xiàn)在對(duì)象還沒(méi)產(chǎn)生,如何使用virtual 函數(shù)來(lái)完成你想完成的動(dòng)作 。
- 靜態(tài)成員函數(shù): 靜態(tài)成員函數(shù)是不依賴于類(lèi)的實(shí)例,而虛函數(shù)是要通過(guò)對(duì)象的虛表(vtable)來(lái)調(diào)用
- 主函數(shù):主函數(shù)是程序的入口點(diǎn),以此不會(huì)被聲明為虛函數(shù) 。