【面試八股總結】面向對象三大特性、虛函數、純虛函數、虛繼承

參考資料:阿秀

一、面向對象三大特性

封裝:將數據和代碼捆綁在一起,避免外界干擾和不確定性訪問

繼承:讓某種類型對象獲得另一個類型對象的屬性和方法

多態:同一種事務表現出不同事務的能力,即:向不同對象發送同一消息,不同的對象在接收時會產生不同的行為

????????重載實現編譯時多態,虛函數實現運行時多態。

實現多態的兩種方式:

  • 覆蓋:子類重新定義父類的虛函數做法
  • 重載:允許存在多個同名函數,而這些函數的參數表不同(參數個數不同、或者參類型不同、或者兩者都不同)

二、虛函數

????????在基類的函數前加上virtual關鍵字,在派生類中重寫該函數,運行時將會根據所指對象的實際類型來調用相應的函數,如果對象類型是派生類,就調用派生類的函數,如果對象類型是基類,就調用基類的函數。

底層原理:

  • 虛表: 虛函數表的縮寫,類中含有virtual關鍵字修飾的方法時,編譯器會自動生成虛表
  • 虛表指針: 在含有虛函數的類實例化對象時,對象地址的前四個字節存儲的指向虛表的指針

上圖展示了虛表和虛表指針在基類對象和派生類對象中的模型,那么多態具體是如何實現的呢?

1. 對象初始化

  • 編譯器會自動為每個含有虛函數的類生成一份虛表,該表時一個一維指針數組,虛表中保存了虛函數的入口地址。
  • 編譯器會在每個對象的前四個字節中保存一個虛表指針vptr,指向對象所屬類的虛表。在構造時,根據對象的類型初始化虛指針vptr,從而讓虛指針指向正確的虛表。
  • 在派生類定義對象時,程序會自動調用構造函數,在構造函數中創建虛表并對虛表初始化。

2. 虛指針指向

  • 當派生類對基類的虛函數沒有重寫時,派生類的虛表指針指向的是基類的虛表;
  • 當派生類對基類的虛函數重寫時,派生類的虛表指針指向的是自身的虛表;
  • 當派生類中有自己的虛函數時,在自己的虛表指針中將此虛函數地址添加在后面。

這樣指向派生類的基類指針在運行時,可以根據派生類對虛函數重寫情況動態進行調用,從而實現多態性。

構造函數和析構函數可以聲明為虛函數嗎?

????????構造函數不能定義為虛函數,析構函數可以為虛函數,并且一般情況下基類析構函數都要定義為虛函數。

????????構造函數:每個含有虛函數的類都有一個虛表指針,指向虛函數表。如果構造函數時虛函數,就需要通過虛表指針尋找虛函數表,從而找到對應的虛函數實現。但是類對象還沒有初始化,就沒有虛表指針,找不到虛函數,所以構造函數不能時虛函數。

????????析構函數:只有在基類析構函數是虛函數時,調用delete操作符銷毀指向派生類的基類指針時,才能準確調用派生類的析構函數,而派生類的析構函數又自動調用基類的析構函數,這樣整個派生類的對象完全被釋放。

三、純虛函數

虛函數和純虛函數的區別?

  • 虛函數是為了實現動態編譯產?的,目的是通過基類類型的指針指向不同對象時,自動調用相應的、和基類同名的函數(使?同?種調用形式,既能調用派生類又能調用基類的同名函數)。虛函數需要在基類中加上 virtual修飾符修飾,因為virtual會被隱式繼承,所以子類中相同函數都是虛函數。當?個成員函數被聲明為虛函數之后,其派生類中同名函數自動成為虛函數,在派生類中重新定義此函數時要求函數名、返回值類型、參數個數和類型全部與基類函數相同。
  • 純虛函數只是相當于?個接口名,但含有純虛函數的類不能夠實例化

純虛函數首先是虛函數,其次沒有函數體,取而代之使用“=0”代替。

它的函數指針會被存在虛函數表中,由于純虛函數并沒有具體的函數體,因此他在虛函數表中的值為0,其他有函數體的虛函數則是函數的具體地址。

一個類中如果存在純虛函數,稱為抽象類,抽象類不能用于實例化,一般用于定義一些公有方法。子類繼承抽象類也必須實現其中的純虛函數才能實例化對象。

四、虛擬繼承

一個類可以從多個基類(父類)繼承屬性和行為。在C++等支持多重繼承的語言中,一個派生類可以同時擁有多個基類。

多重繼承可能引入一些問題,如萎形繼承問題,比如當一個類同時繼承了兩個擁有相同基類的類,而最終的派生類又同時繼承了這兩個類時,可能導致二義性和代碼設計上的復雜性。為了解決這些問題,C++ 提供了虛繼承,通過在繼承聲明中使用 virtual 關鍵字,可以避免在派生類中生成多個基類的實例,從而解決了菱形繼承帶來的二義性。

舉個🌰:

#include <iostream>using namespace std;class A{}class B : virtual public A{};class C : virtual public A{};class D : public B, public C{};int main(){cout << "sizeof(A):" << sizeof A <<endl; // 1,空對象,只有?個占位cout << "sizeof(B):" << sizeof B <<endl; // 4,?個bptr指針,省去占位,不需要對?cout << "sizeof(C):" << sizeof C <<endl; // 4,?個bptr指針,省去占位,不需要對?cout << "sizeof(D):" << sizeof D <<endl; // 8,兩個bptr,省去占位,不需要對?}

上述代碼所體現的關系是,B和C虛擬繼承A,D公有繼承B和C,這種方式是?種菱形繼承或者鉆石繼承,可以用下圖來表示:

? ? ? ? 虛擬繼承的情況下,無論基類被繼承多少次,只會存在一個實體。

????????虛擬繼承基類的子類中,子類會增加某種形式的指針,或者指向虛基類子對象,或者指向一個相關表格;表格中存放的不是虛基類子對象的地址,就是其偏移量,此類指針被稱為bptr。如果即存在vptr又存在bptr,某些編譯器會將其優化,合并為一個指針。

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

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

相關文章

紅黑樹,B+樹,B樹的結構原理及對比

紅黑樹 結構原理&#xff1a; 紅黑樹是一種自平衡的二叉搜索樹&#xff0c;它通過在每個節點上增加一個顏色屬性&#xff08;紅色或黑色&#xff09;來確保樹的平衡性。紅黑樹的平衡是通過一系列旋轉和重新著色操作來實現的&#xff0c;這些操作在插入、刪除節點時進行&#…

數據庫課設---學生宿舍管理系統(sql server+C#)

1.引言 1.1 內容及要求 設計內容&#xff1a;設計學生宿舍管理系統。 設計要求&#xff1a; &#xff08;1&#xff09;數據庫應用系統開發的需求分析&#xff0c;寫出比較完善系統功能。 &#xff08;2&#xff09;數據庫概念模型設計、邏輯模型設計以及物理模型設計。 …

yolov8 人體姿態識別

引言 在計算機視覺的各種應用中&#xff0c;人體姿態檢測是一項極具挑戰性的任務&#xff0c;它能夠幫助我們理解人體各部位的空間位置。本文將詳細介紹如何使用 YOLOv8 和 Python 實現一個人體姿態檢測系統&#xff0c;涵蓋模型加載、圖像預處理、姿態預測到結果可視化的全流…

Echarts水球圖(liquidFill)添加文字

效果 代碼 {type: liquidFill,shape: shapes[0].value,radius: 90%,data: [{name: 獨立百貨,value: 0}],center: [50%, 50%],color: [{type: linear,x: 0,y: 0,x2: 0,y2: 1,colorStops: [{offset: 0,color: #446bf5},{offset: 1,color: #2ca3e2}],globalCoord: false}],backgro…

JSP實現簡單的登錄和注冊

JSP實現登錄和注冊&#xff08;Map集合模擬數據庫&#xff09; 1、login.jsp2、 loginSelect.jsp3、register.jsp4、 RegisterSelect.jsp5、 index.jsp 1、login.jsp login.jsp中username和password在LoginSelect.jsp驗證是否一致使用session.setAttribute("login_msg&quo…

RTOS系統 -- ARM Cortex-M4 RPMSG之通道初始化函數

RPMsg Lite 在 ARM Cortex-M4 RTOS 中的使用 簡介 在ARM Cortex-M4處理器上使用的RTOS&#xff08;實時操作系統&#xff09;中&#xff0c;rpmsg_lite是一個輕量級的遠程處理消息傳遞框架&#xff0c;通常用于多核處理器或多核系統中不同處理器之間的通信。本文檔將介紹 rpm…

ffmpeg轉換MP4為gif命令

這里記錄一下使用 ffmpeg去轉化 gif 的一些快捷命令 # 直接轉換 ffmpeg -i 222.mp4 -r 12 222.gif# 調色板優化處理 ffmpeg -i 222.mp4 -r 12 -vf "split[s0][s1];[s0]palettegen[p];[s1][p]paletteuse" 222.gif第二條命令的解釋如下&#xff1a; split[s0][s1]&am…

nginx設置代理解決跨域問題

vue工程 npm run build 后把dist包放到 nginx代理服務器的html目錄&#xff0c;在conf/nginx.conf配置文件中增加配置&#xff0c;這樣就可以正常方位后端接口了&#xff0c;配置如下&#xff1a; server {listen 8193;server_name localhost 127.0.0.1;location / {root D:…

【RHCE】dns實驗0707

題目&#xff1a; 做法: 1.創建兩個虛擬機 張三&#xff1a;且有加密 李四&#xff1a; 設置zhangsan/lisi對應的html網頁 主服務器測試&#xff1a; 證書驗證 2.配置dns 主服務器&#xff1a; 區域文件&#xff08;zs/lisi&#xff09; 從服務器&#xff1a; 且dns為主服務…

OZON生活家居用品爆款新品

OZON生活家居用品爆款新品涵蓋了多個方面&#xff0c;這些產品不僅滿足了消費者對生活品質的追求&#xff0c;也反映了當前市場的熱門趨勢。以下是一些在OZON平臺上備受關注的生活家居用品爆款新品&#xff1a; OZON生活家居用品爆款新品工具&#xff1a;D。DDqbt。COm/74rD T…

Midway Serverless 發布 2

可以看看優化后的開發情況&#xff0c;不僅和應用一樣&#xff0c;速度還比較快&#xff0c;也不會生成臨時目錄&#xff0c;修改實時生效。 這是 v2.0 和 v1.0 的根本性變化&#xff0c;也是整體架構升級帶來的巨大優勢。 當然&#xff0c;這一塊并不是功能的新增&#xff0c…

UI 自動化分布式測試 -- Docker Selenium Grid

UI 自動化分布式測試 – Docker Selenium Grid Docker 和 Selenium Grid 的結合為分布式 UI 自動化測試提供了一種高效、可擴展且易于管理的方法。通過使用 Docker 容器化技術&#xff0c;測試環境的設置和配置變得更加簡便和一致&#xff1b;而 Selenium Grid 則允許在多個節…

電腦清理c盤內存空間怎么清理免費 怎么清理c盤的垃圾文件又不刪除有用文件

在計算機使用過程中&#xff0c;隨著時間的推移&#xff0c;C盤空間可能會被各種臨時文件、緩存和無用的注冊表項占用。這不僅會導致C盤空間不足&#xff0c;還可能影響計算機的性能。那么怎么樣清理C盤內存空間&#xff0c;怎么樣清理C盤的垃圾避開系統文件呢&#xff1f; 一…

?? 翻頁 上一頁/下一頁

data里面定義 currentPage: 0 // 當前頁數 created 初始化時賦值 this.formProps 是表格 要求是對象 this.contractArr 是傳過來要進行分頁的數組對象 初始化顯示第一個created() {this.formProps this.contractArr[0]} html頁面 <div><div>// 左箭頭<s…

linux 進程堆棧分析

1.進程pid jsp -l | grep appName 或 ps -ef | grep appName 2.查看cpu top -c pidps -mp pid-o THREAD,tid,time / top -H -p pid #打印出進程對應的線程id及運行時間timeprintf %x\n 線程id3.查看gc jstat -gcutil | grep pid 500jstat -class pid4.查看進程日志 jsta…

數據分析案例-2024 年全電動汽車數據集可視化分析

&#x1f935;?♂? 個人主頁&#xff1a;艾派森的個人主頁 ?&#x1f3fb;作者簡介&#xff1a;Python學習者 &#x1f40b; 希望大家多多支持&#xff0c;我們一起進步&#xff01;&#x1f604; 如果文章對你有幫助的話&#xff0c; 歡迎評論 &#x1f4ac;點贊&#x1f4…

Navicat BI 教程 | 圖表設計和儀表板

商業智能&#xff08;Business Intelligence&#xff0c;BI&#xff09;是將數據轉化為可操作的洞察力的實踐&#xff0c;使組織能夠簡化生產力和實現更好的整體績效。本博客最近介紹了新的 Navicat BI&#xff0c;這是一個幫助 BI 專業人員通過創建數據可視化&#xff08;如圖…

侯捷C++面向對象高級編程(上)-11-虛函數與多態

1.虛函數 2.virtual 3.繼承&#xff0b;復合關系下的構造和析構 4.委托&#xff0b;繼承

Shell學習——Shell運算符

文章目錄 運算符算術運算符關系運算符布爾運算符邏輯運算符字符串運算符 運算符 算術運算符 #!/bin/bash a10 b20valexpr $a $b echo "a b : $val"valexpr $a - $b echo "a - b : $val"valexpr $a \* $b echo "a * b : $val"valexpr $b / $a…

C語言 | Leetcode C語言題解之第221題最大正方形

題目&#xff1a; 題解&#xff1a; int maximalSquare(char** matrix, int matrixSize, int* matrixColSize){int dp[301][301]{0};int wid0;if(matrixSize0&&matrixColSize[0]0){return 0;}for(int i0;i<matrixSize;i){for(int j0;j<matrixColSize[0];j){if(m…