【C++】虛函數

類中聲明函數成員的時候,在函數的前面加上virtual關鍵字,則該成員為虛函數

虛函數的特點

  1. 如果在類中定義的虛函數,那么系統會為這個類維護一個虛函數表
  2. 類中會多出4個字節的指針去指向這個虛函數表,在虛函數表中保存了虛函數的首地址,在調用虛函數的時候就會先到表中查找虛函數,然后調用,就比普通函數多了步操作
  3. 虛函數表不會被繼承,但是表中的項會被繼承(虛函數會被繼承)

虛函數的作用

通過類的繼承及虛函數來實現多態

  1. 有兩個類,他們之間是父子關系
  2. 子類和父類有同名的虛函數,但是功能不同
  3. 父類指針或引用指向父類或子類對象,指向哪個對象就可以調用哪個對象的虛函數成員

示例:

#include<iostream>
using namespace std;class Animal {
public:virtual void speak() {cout << "動物在說話" << endl;}
};class Cat :public Animal {
public:virtual void speak() {//子類重寫父類的虛函數cout<<"貓在喵喵叫" << endl;}
};
int main() {//調用:父類指針指向子類對象Animal* p = new Cat;p->speak();//調用的是Cat的speak()delete p;
}

多態下釋放的注意事項

基類中有虛函數時,且通過父類指針去分配子類對象的時候,在釋放的時候只能通過父類指針去進行釋放,在delete父類指針的時候會調用父類的析構函數,而不會調用子類的析構函數;需要把父類的析構函數定義為虛析構,那么在釋放父類指針的時候也就會調用子類的析構函數了。

以上面示例為例:

#include<iostream>
using namespace std;class Animal {
public:virtual ~Animal() {cout << "調用了父類析構" << endl;}virtual void speak() {cout << "動物在說話" << endl;}
};class Cat :public Animal {
public:~Cat() {cout << "調用了子類析構" << endl;}virtual void speak() {//子類重寫父類的虛函數cout<<"貓在喵喵叫" << endl;}
};
int main() {//調用:父類指針指向子類對象Animal* p = new Cat;p->speak();//調用的是Cat的speak()delete p;
}

輸出:

貓在喵喵叫
調用了子類析構
調用了父類析構

注意:構造函數不能是虛函數

純虛函數

純虛函數是一種特殊的虛函數。在基類中不能為虛函數給出有意義的實現,就可以把它聲明為純虛函數,然后把它的實現留給派生類去完成。

定義:virtual 函數返回值類型 函數名(函數參數)=0;

在C++中沒有interface關鍵字,“接口”的概念靠純虛函數實現

示例:

#include<iostream>
#include<string>class Printable {
public:virtual std::string GetID() = 0;void PrintID() {std::cout << this->GetID() << std::endl;}
};class Student :public Printable {
public:std::string StuID = "S123456";std::string GetID() override {return StuID;}
};class Teacher :public Printable{
public:std::string TeaID = "T654321";std::string GetID() override {return TeaID;}
};int main() {Student stu;stu.PrintID();Teacher tea;tea.PrintID();
}

Student類和Teacher類可以看作是實現了“Printable接口”

純虛析構

析構函數也可以聲明成純虛析構,類內寫聲明,不用實現;但要在類外實現。

virtual ~類名()=0;//純虛析構的類內聲明
類名::~類名(){};//純虛析構的類外實現

抽象類

  1. 在一個類中具有一個及以上純虛函數,那么這個類被稱之為抽象類
  2. 抽象類不能實例化對象,但是可以定義指針,只能作為基類為派生類服務
  3. 如果派生類中沒有完全實現基類中所有的純虛函數,那么該派生類也會變成抽象類,同樣不能實例化對象

final

  • 可以阻止成員函數的重寫:virtual void fun() final
  • 可以阻止類的繼承:class C1 final

注:一個抽象類被阻止繼承,那么這個類就沒有任何作用(一般不會這樣寫)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/62408.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/62408.shtml
英文地址,請注明出處:http://en.pswp.cn/web/62408.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

如何在UI自動化測試中創建穩定的定位器?

如何在UI自動化測試中創建穩定的定位器&#xff1f; 前言1. 避免使用絕對路徑2. 避免在定位器中使用索引3. 避免多個類名的定位器4. 避免動態和自動生成的ID5. 確保定位器唯一6. 處理隱藏元素的策略7. 謹慎使用基于文本的定位器8. 使用AI創建穩定的定位器 總結 前言 在自動化測…

明日宣講 香港科技大學廣州|數據科學與分析學域碩博招生宣講會【湖南大學專場】

&#x1f4e3;&#x1f4e3;&#x1f4e3;明日宣講 香港科技大學廣州&#xff5c;數據科學與分析學域碩博招生宣講會【湖南大學專場】 時間&#xff1a;2024年12月10日&#xff08;星期二&#xff09;15:00 地點&#xff1a;湖南大學信息科學與工程學院624會議室 報名鏈接&…

BurpSuite-8(FakeIP與爬蟲審計)

聲明&#xff1a;學習視頻來自b站up主 瀧羽sec&#xff0c;如涉及侵權馬上刪除文章 感謝瀧羽sec 團隊的教學 視頻地址&#xff1a;IP偽造和爬蟲審計_嗶哩嗶哩_bilibili 一、FakeIP 1.配置環境 BurpSuite是java環境下編寫的&#xff0c;而今天的插件是python編寫的&#xff0c…

2024 一帶一路暨金磚國家技能發展與技術創新大賽【網絡安全防護治理實戰技能賽項】樣題(中職組)

2024 一帶一路暨金磚國家技能發展與技術創新大賽【網絡安全防護治理實戰技能賽項】樣題&#xff08;中職組&#xff09; 1.基礎設置和安全強化&#xff08;xxx 分&#xff09;1.3. 任務內容: 2.安全監測和預警&#xff08;xxx 分&#xff09;2.1. 任務一&#xff1a;建立目錄安…

Qt C++ 顯示多級結構體,包括結構體名、變量名和值

文章目錄 mainwindow.hmainwindow.cppstructures.hmain.cpp QTreeView 和 QStandardItemModel 來實現。以下是實現這一功能的步驟和示例代碼&#xff1a; 定義多級結構體&#xff1a; 假設你有一個多級結構體&#xff0c;如下所示&#xff1a; struct SubStruct {int subValue…

CISC和RISC的區別

CISC是什么 CISC是一種指令集設計方式&#xff0c;全程叫復雜指令集&#xff0c;這種指令設計模式包含大量的復雜指令和復雜的尋址方式&#xff0c; 以下是CISC架構的一些主要特點&#xff1a; 豐富的指令集&#xff1a;CISC處理器通常包含大量的指令&#xff0c;這些指令覆蓋…

20 設計模式之職責鏈模式(問題處理案例)

一、什么是職責鏈模式 職責鏈模式是一種行為型設計模式&#xff0c;它允許將請求沿著處理者的鏈進行傳遞&#xff0c;直到有一個處理者能夠處理它為止。換句話說&#xff0c;它將請求的發送者和接收者解耦&#xff0c;使得多個對象都有機會處理這個請求&#xff0c;從而避免了將…

linux基于systemd自啟守護進程 systemctl自定義服務傻瓜式教程

系統服務 書接上文: linux自啟任務詳解 演示系統:ubuntu 20.04 開發部署項目的時候常常有這樣的場景: 業務功能以后臺服務的形式提供,部署完成后可以隨著系統的重啟而自動啟動;服務異常掛掉后可以再次拉起 這個功能在ubuntu系統中通常由systemd提供 如果僅僅需要達成上述的場…

ros項目dual_arm_pick-place(moveit和gazebo聯合仿真)(一)

目錄 前言正文創建功能包具體代碼運行 總結 前言 dual_arm_pick-place項目中&#xff0c;實現了兩套的moveit和gazebo聯合仿真。 啟動文件分別是bringup_moveit.launch和arm_bringup_moveit.launch。 在這個項目中&#xff0c;我將代碼重新創建了一個包&#xff0c;co_simula…

MySQL 索引(B+樹)詳解

MySQL 索引&#xff08;B樹&#xff09;詳解 MySQL邏輯架構對比InnoDB與MyISAM存儲結構存儲空間可移植性、備份及恢復事務支持AUTO_INCREMENT表鎖差異全文索引表主鍵表的具體行數CRUD操作外鍵 sql優化簡介什么情況下進行sql優化sql語句執行過程sql優化就是優化索引 索引索引的優…

MySQL生產環境備份腳本

全量備份腳本&#xff0c;其中BakDir&#xff0c;ZlbakDir&#xff0c;LogFile需要自己創建 #!/bin/bash export LANGen_US.UTF-8# 指定備份目錄 BakDir/root/beifen/data/mysqlbak/data/allbak # 指定增量備份目錄 ZlbakDir/root/beifen/data/mysqlbak/data/zlbak # 備份日志…

HTTP multipart/form-data 請求

序言 最近在寫項目的過程中有一個需求是利用 HTTP 協議傳輸圖片和視頻&#xff0c;經過查詢方法相應的方法發現使用 multipart/form-data 的方式&#xff0c;這是最常見處理二進制文件的表單編碼類型。 ?學習了一下午&#xff0c;現在總結一下使用的方法和相關的知識點&#x…

Linux下redis環境的搭建

1.redis的下載 redis官網下載redis的linux壓縮包&#xff0c;官網地址:Redis下載 網盤鏈接&#xff1a; 通過網盤分享的文件&#xff1a;redis-5.0.4.tar.gz 鏈接: https://pan.baidu.com/s/1cz3ifYrDcHWZXmT1fNzBrQ?pwdehgj 提取碼: ehgj 2.redis安裝與配置 將包上傳到 /…

如何使用靜態IP代理?【詳細教程】

靜態IP地址是手動分配給設備或伺服器的固定不變的 IP。與動態 IP 地址不同&#xff0c;動態 IP 地址由 DHCP 伺服器自動分配&#xff0c;並且會隨時間而變化。??????? 如何獲取和設置靜態IP地址 一、檢查是否需要靜態IP&#xff1f; 在配置靜態 IP 之前&#xff0c;請…

監控組態軟件的構成與功能

監控組態軟件的構成包括系統開發環境、圖形界面系統、實時數據庫系統等。其功能包括數據采集與控制、人機交互界面、數據處理與存儲等。 監控組態軟件的構成&#xff1a; 系統開發環境&#xff1a;這是自動化工程設計工程師為實施其控制方案&#xff0c;在組態軟件的支持下進行…

Java 基礎之 XQuery:強大的 XML 查詢語言

一、什么是 XQuery XQuery 是一種函數式語言&#xff0c;專門用于檢索以 XML 格式存儲的信息。它負責從 XML 文檔中查找和提取元素及屬性&#xff0c;在網絡服務中有著廣泛的應用&#xff0c;比如提取信息、生成摘要報告、進行數據轉換等。 XQuery 是 W3C 設計的一種針對于 X…

day09性能測試(1)——純理論

document.querySelector(video).playbackRate 2.5 //可以寫任何數字 【沒有所謂的運氣&#x1f36c;&#xff0c;只有絕對的努力?】 目錄 1、性能測試概念 2、功能測試 vs 性能測試 3、小結&#xff08;習題&#xff09; 4、性能測試的策略 4.1 基準測試 4.2 負載測試 …

docker-3.docker權限問題

docker權限,每次開機都要重新sudo 目錄 1.簡介2.解決辦法1:當前用戶添加到docker用戶組(這個方法還是缺權限??)3.解決辦法2:臨時更改Docker socket文件權限1.簡介 Ubuntu下Docker提示permission denied (權限不足)解決辦法 安裝docker后,執行docker ps命令時提示 perm…

easyExcel實現表頭批注

背景&#xff1a; 網上大部分都不能直接使用&#xff0c;為此總結一個方便入手且可用的工具&#xff0c;用自定義注解實現 依賴包&#xff1a; <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>…

內部類和Object類

匿名對象 格式&#xff1a; 匿名對象只可以調用一次成員 &#xff1a; 1. 調用一次成員變量 &#xff1a; new 類名(實參).成員變量名&#xff1b; 2.調用一次成員方法&#xff1a; new 類名(實參).成員方法名(實參)&#xff1b; 匿名對象存在的必要&#xff1a;為了提高…