虛函數(shù)是C++面向?qū)ο缶幊讨械木柚唬鼮槲覀兲峁┝硕鄳B(tài)性的魔法鑰匙。
在C++中,虛函數(shù)是一種允許在派生類中重新定義的函數(shù)。其背后的核心思想是多態(tài)性,通過在基類中聲明虛函數(shù),我們可以以一種統(tǒng)一的方式處理不同類型的對象。讓我們先來看一個簡單的例子:
#include <iostream>using namespace std;class Shape {public: virtual void draw() { cout << "Drawing a shape" << endl; }};class Circle : public Shape {public: void draw() override { cout << "Drawing a circle" << endl; }};class Square : public Shape {public: void draw() override { cout << "Drawing a square" << endl; }};int main() { Circle circle; Square square; // 使用基類指針調(diào)用虛函數(shù),實(shí)現(xiàn)多態(tài) Shape* shape1 = &circle; Shape* shape2 = &square shape1->draw(); // 輸出 "Drawing a circle" shape2->draw(); // 輸出 "Drawing a square" return 0;}
通過上述代碼,我們定義了一個基類 Shape 和兩個派生類 Circle 和 Square。它們都重寫了基類的虛函數(shù) draw。在 main 函數(shù)中,我們使用基類指針調(diào)用虛函數(shù),實(shí)現(xiàn)了多態(tài)性,即使指針指向的是派生類的對象,也能正確地調(diào)用相應(yīng)的函數(shù)。
(1) 運(yùn)行時綁定
虛函數(shù)的一個關(guān)鍵性質(zhì)是運(yùn)行時綁定,也稱為動態(tài)綁定。這意味著程序在運(yùn)行時根據(jù)對象的實(shí)際類型來確定調(diào)用的函數(shù)版本,而不是在編譯時確定。這種動態(tài)性為程序提供了更大的靈活性和適應(yīng)性。
(2) 虛函數(shù)表(vtable)
在實(shí)現(xiàn)上,虛函數(shù)通過虛函數(shù)表(vtable)來實(shí)現(xiàn)。每個包含虛函數(shù)的類都有一個與之相關(guān)的虛函數(shù)表,其中存儲了該類中虛函數(shù)的地址。派生類繼承了基類的虛函數(shù)表,并可以在其中添加或重寫函數(shù)。這一機(jī)制確保了在運(yùn)行時正確調(diào)用函數(shù)的地址。
(1) 當(dāng)存在繼承關(guān)系時
虛函數(shù)主要用于處理基類和派生類之間的繼承關(guān)系。當(dāng)你希望在基類中定義一個通用的接口,而在派生類中實(shí)現(xiàn)特定的行為時,虛函數(shù)是一個理想的選擇。
class Animal {public: virtual void makeSound() { cout << "Generic animal sound" << endl; }};class Dog : public Animal {public: void makeSound() override { cout << "Woof! Woof!" << endl; }};class Cat : public Animal {public: void makeSound() override { cout << "Meow!" << endl; }};
(2) 需要實(shí)現(xiàn)多態(tài)性
當(dāng)你希望以一致的方式處理不同類型的對象時,虛函數(shù)是實(shí)現(xiàn)多態(tài)性的關(guān)鍵。通過在基類中聲明虛函數(shù),并在派生類中進(jìn)行重寫,你可以在運(yùn)行時選擇調(diào)用哪個版本的函數(shù),從而實(shí)現(xiàn)多態(tài)性。
(1) 虛函數(shù)的聲明與定義
在基類中,虛函數(shù)需要在聲明和定義時都加上 virtual 關(guān)鍵字。這告訴編譯器這是一個虛函數(shù),需要在運(yùn)行時進(jìn)行動態(tài)綁定。
class Base {public: // 基類中的虛函數(shù)聲明 virtual void show(); // 基類中的虛函數(shù)定義 virtual void display() { cout << "Base class display function" << endl; }};
(2) 純虛函數(shù)的形式
虛函數(shù)還可以是純虛函數(shù),即在基類中只聲明而不定義。這樣的虛函數(shù)需要在派生類中進(jìn)行實(shí)現(xiàn),否則派生類也會成為抽象類。
class AbstractBase {public: // 純虛函數(shù)聲明 virtual void pureVirtualFunction() = 0; // 普通虛函數(shù)聲明 virtual void normalVirtualFunction();}
讓我們通過一個美圖秀秀插件系統(tǒng)的實(shí)例來展示虛函數(shù)的威力,其中有基類 Plugin,以及它的兩個派生類 FilterPlugin 和 DrawingPlugin。
#include <iostream>using namespace std;class Plugin {public: virtual void apply() { cout << "Applying a generic plugin" << endl; }};class FilterPlugin : public Plugin {//濾鏡插件public: void apply() override { cout << "Applying a filter plugin" << endl; }};class DrawingPlugin : public Plugin {//繪圖插件public: void apply() override { cout << "Applying a drawing plugin" << endl; }};
在這個例子中,Plugin 類有一個虛函數(shù) apply(),而派生類濾鏡插件FilterPlugin和繪圖插件DrawingPlugin 分別實(shí)現(xiàn)了自己的版本。通過使用基類指針,我們可以實(shí)現(xiàn)多態(tài)性,以一致的方式處理不同插件:
int main() { FilterPlugin filter; DrawingPlugin drawing; // 使用基類指針調(diào)用虛函數(shù),實(shí)現(xiàn)多態(tài) Plugin* plugin1 = &filter; Plugin* plugin2 = &drawing; plugin1->apply(); // 輸出 "Applying a filter plugin" plugin2->apply(); // 輸出 "Applying a drawing plugin" return 0;}
通過這個實(shí)例,我們看到了虛函數(shù)如何在美圖秀秀系統(tǒng)中實(shí)現(xiàn)多態(tài)性,使得我們能夠以一致的方式處理不同類型的業(yè)務(wù)功能。
虛函數(shù)是C++中一個強(qiáng)大而靈活的特性,它為多態(tài)性的實(shí)現(xiàn)提供了基礎(chǔ)。通過深入理解虛函數(shù),我們能夠?qū)懗龈屿`活、可擴(kuò)展且易于維護(hù)的面向?qū)ο蟠a。
本文鏈接:http://www.tebozhan.com/showinfo-26-66545-0.html探秘C++虛函數(shù):多態(tài)的奇妙世界
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com
上一篇: Npm 淘寶鏡像到期了,盡快切換