C++多態的實現原理

靜態多態(編譯期)

函數重載

  • 允許在同一個作用域中聲明多個功能類似的同名函數
  • 函數的參數列表不同(參數個數,參數類型,參數順序)
  • 注意:不能通過函數返回值區分(name mangling不包括返回值)

原理

  • 預編譯:頭文件的函數聲明拷貝到源文件,避免編譯過程找不到函數定義
  • 編譯:語法分析,同時進行符號匯總(函數名)
  • 匯編:生成函數名到函數地址的映射,方便之后通過函數名找到函數定義的位置
  • 鏈接:將多個文件的符號表匯總合并

*objdump -t o

  • _ZN + 類長度+ 類名+ 函數名長度 + 函數名 + E + 類型首字母

模版

  • 編譯期間進行實例化
  • 性能要高,避免了運行時的開銷

動態多態

虛函數重寫,運行時確定

  • 在基類的函數前面加上virtual關鍵字,派生類重寫函數
  • 運行時根據對象的類型調用相應的函數
  • 如果對象的類型是基類,則調用基類的函數
  • 如果對象的類型是派生類,調用派生類的函數

原理

  • 早綁定:編譯時已經確定函數調用的地址
  • 晚綁定:需要用到虛函數表,運行時才能確定

早綁定(Early Binding)

早綁定,也稱為靜態綁定(Static Binding),是在編譯時確定函數調用的具體實現。這意味著在編譯階段,編譯器已經知道函數調用對應的具體函數。早綁定通常與非虛函數、函數重載和模板有關。

早綁定的優點:

  1. 性能高,因為函數調用在編譯時已確定,不需要運行時查找。
  2. 類型安全,因為編譯器在編譯時進行類型檢查,可以捕捉到類型不匹配的錯誤。

示例:

#include <iostream>
using namespace std;class Base {
public:void display() {cout << "Base display" << endl;}
};class Derived : public Base {
public:void display() {cout << "Derived display" << endl;}
};int main() {Base b;Derived d;Base *ptr = &d;ptr->display(); // 調用 Base::display()return 0;
}

在上述示例中,ptr->display() 是早綁定,因為編譯器在編譯時已經知道 ptrBase 類型的指針,并且調用 Base 類的 display 函數。

晚綁定(Late Binding)

晚綁定,也稱為動態綁定(Dynamic Binding),是在運行時確定函數調用的具體實現。這通常通過虛函數(virtual functions)和多態性實現。晚綁定依賴于虛函數表(vtable),通過指針在運行時查找函數的具體實現。

晚綁定的優點:

  1. 靈活性高,允許程序在運行時決定調用哪個函數。
  2. 支持多態性,使得可以通過基類指針調用派生類的實現。

示例:

#include <iostream>
using namespace std;class Base {
public:virtual void display() {cout << "Base display" << endl;}
};class Derived : public Base {
public:void display() override {cout << "Derived display" << endl;}
};int main() {Base *ptr = new Derived();ptr->display(); // 調用 Derived::display()delete ptr;return 0;
}

在上述示例中,ptr->display() 是晚綁定,因為 display 是虛函數,具體調用的函數是在運行時根據對象的實際類型(即 Derived)決定的。

最后給大家推薦一個LinuxC/C++高級架構系統教程的學習資源與課程,可以幫助你有方向、更細致地學習C/C++后端開發,具體內容請見 https://xxetb.xetslk.com/s/1o04uB

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

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

相關文章

(補充)IDEA項目結構

文章目錄 前言一、pycharm中Python項目結構二、IDEA中的java項目結構設計總結前言 本文主要介紹一下pycharm和IDEA里面的項目結構的使用方法 一、pycharm中Python項目結構 之前我們在pycharm做過python項目,項目結構很清晰,還是比較靈活的。 一般項目里面就是 數據驅動、數…

【JavaSE】程序邏輯控制

目錄 1. 順序結構 2. 分支結構 2.1 if語句 2.1.1 語法格式1 2.1.2 語法格式2 2.1.3 語法格式3 2.1.4 練習 2.1.5 注意事項 2.2 switch 語句 3. 循環結構 3.1 while循環 3.1.1 語法格式 3.1.2 代碼示例 3.1.3 注意事項 3.2 break 3.3 continue 3.4 for循環 …

scratch3編程05-畫筆繪制圓及與圓相關的圖形

目錄 一&#xff0c;圓 1&#xff0c;空心圓 2&#xff0c;實心圓 3&#xff0c;嵌套在一起的圓 4&#xff0c;圓環 二&#xff0c;五角星 1&#xff0c;空心五角星 1&#xff09;思路 2&#xff09;完整的程序 2&#xff0c;實心五角星 1&#xff09;思路 2&…

C# 預處理器指令

C# 預處理器指令 概述 C# 預處理器指令是編譯器在編譯代碼之前處理的指令。這些指令用于控制編譯過程,包括條件編譯、編譯指令的定義和取消等。預處理器指令以 # 開頭,不包含在代碼的執行邏輯中,僅在編譯階段起作用。 常用的預處理器指令 1. #define 和 #undef #define…

RK3568筆記三十三: helloworld 驅動測試

若該文為原創文章&#xff0c;轉載請注明原文出處。 報著學習態度&#xff0c;接下來學習驅動是如何使用的&#xff0c;從簡單的helloworld驅動學習起。 開始編寫第一個驅動程序—helloworld 驅動。 一、環境 1、開發板&#xff1a;正點原子的ATK-DLRK3568 2、系統&#xf…

d3dcompiler_43.dll文件是什么?如何快速有效的解決d3dcompiler_43.dll文件丟失問題

dcompiler_43.dll 是一個Windows系統中的系統文件&#xff0c;屬于DirectX軟件的一部分。這個dcompiler_43.dll&#xff08;動態鏈接庫&#xff09;文件主要用于處理與3D圖形編程有關的任務&#xff0c;是運行許多游戲和高級圖形程序必需的組件之一。那么如果電腦丟失d3dcompil…

香蕉派BPI-Wifi6迷你路由器公開發售

Banana Pi BPI-Wifi6 Mini 公開發售。 Banana Pi BPI-Wifi6 Mini 開源路由器采用Triductor TR6560 TR5220 wifi SOC設計&#xff0c;是一款迷你尺寸的wifi6路由器解決方案。內置高性能雙核ARM Cortec A9處理器用于WIFI報文轉發或智能業務處理&#xff0c;內置高性能LSW和硬件N…

[NeetCode150] String Encode and Decode

String Encode and Decode Design an algorithm to encode a list of strings to a single string. The encoded string is then decoded back to the original list of strings. Please implement encode and decode Example 1: Input: [“neet”,“code”,“love”,“you…

ubuntu 上vscode +cmake的debug調試配置方法

在ubuntu配置pcl點云庫以及opencv庫的時候&#xff0c;需要在CMakeLists.txt中加入相應的代碼。配置完成后&#xff0c;無法調試&#xff0c;與在windows上體驗vs studio差別有點大。 找了好多調試debug配置方法&#xff0c;最終能用的有幾種&#xff0c;但是有一種特別好用&a…

ubuntu部署minio集群

minio集群介紹 官方文檔&#xff1a;https://min.io/docs/minio/linux/operations/install-deploy-manage/deploy-minio-multi-node-multi-drive.html 本方案采用在多節點多驅動器 (MNMD) 或“分布式”配置部署 MinIO。 MNMD 部署提供企業級性能、可用??性和可擴展性&#…

jmeter-beanshell學習4-beanshell截取字符串

再寫個簡單點的東西&#xff0c;截取字符串&#xff0c;參數化文件統一用csv&#xff0c;然后還要用excel打開&#xff0c;如果是數字很容易格式就亂了。有同事是用雙引號把數字引起來&#xff0c;報文里就不用加引號了&#xff0c;但是這樣beanshell處理起來&#xff0c;好像容…

Facebook社交平臺的未來發展趨勢分析

隨著科技和社交需求的不斷演變&#xff0c;Facebook作為全球最大的社交平臺之一&#xff0c;其未來發展的趨勢備受關注。從技術創新到社會影響&#xff0c;Facebook正在經歷著前所未有的變化和挑戰。本文將探討Facebook未來發展的幾個關鍵趨勢&#xff0c;并分析其可能的影響和…

[Linux][Shell][Shell變量]詳細講解

目錄 1.本地變量2.變量定義3.取出變量值4.特殊變量5.特殊狀態變量6.shell內置的變量命令1.echo2.eval3.exec 7.截取字符串8.特殊shell擴展變量處理1.語法2.應用場景 1.本地變量 定義Shell變量&#xff0c;變量名不需要加$本地變量只在?戶當前shell?存期中有效 2.變量定義 變…

SpringBoot防止重復提交 AOP+自定義注解+redis

1.什么是重復提交呢 在Web開發中&#xff0c;重復提交&#xff08;也稱為雙重提交或重復表單提交&#xff09;是指用戶在沒有明確意圖的情況下&#xff0c;多次提交同一表單的情況。這可能是由于用戶多次點擊提交按鈕、表單提交過程中的網絡延遲導致用戶重復點擊、或者由于瀏覽…

雙向全橋隔離dc-dc變換器(DAB)

DAB(dual active bridge) 雙向全橋隔離dc-dc變換器&#xff08;DAB&#xff09;和Buck/Boost不同&#xff0c;該變換器通過交流電感進行功率傳輸&#xff0c;其調制和控制不適合直接借鑒已有的研究。 調制挑戰&#xff1a;開關網絡相對復雜&#xff0c;調制自由度較多&#x…

揭秘SQL Server數據庫選項:性能與行為的調控者

揭秘SQL Server數據庫選項&#xff1a;性能與行為的調控者 在SQL Server的世界中&#xff0c;數據庫選項是那些可以調整以優化數據庫性能和行為的設置。它們是數據庫管理員和開發者的得力助手&#xff0c;通過精細調控&#xff0c;可以顯著提升數據庫的響應速度和資源利用率。…

MySQL MVCC

總結自小林coding&#xff0c;bojiangzhou 臟讀、不可重復讀、幻讀 說的都是并發讀取的問題&#xff0c;最簡單的方式就是給記錄加一把鎖&#xff0c;不管是更新、讀取記錄都需要競爭到這把鎖之后才能操作。但這種方式的并發性能可想而知會有多么低。 于是 InnoDB 就設計了MVC…

C#——二進制流序列化和反序列化

C#二進制流序列化和反序列化 在C#中&#xff0c;可以使用BinaryFormatter來進行二進制的序列化和反序列化。 首先&#xff0c;定義一個可序列化的類 [Serializable] public class MyObject {public int IntProperty { get; set; }public string StringProperty { get; set; …

ubuntu 上配置開機自動啟動ssh

一般安裝了就會自動啟動。但是各種rc.local, cron都測試了一下&#xff0c;還是這個systemd有效 使用 systemd 服務 創建文件 sudo nano /etc/systemd/system/custom-ssh.service [Unit] DescriptionStart SSH service at boot Afternetwork.target[Service] ExecStart/usr/…

軟件開發(續).NET框架

1.解釋一下.NET框架中的CLR&#xff08;公共語言運行時&#xff09;是什么&#xff0c;以及它的作用和功能是什么&#xff1f; CLR&#xff08;Common Language Runtime&#xff09;的概念和作用 在.NET框架中&#xff0c;CLR&#xff08;Common Language Runtime&#xff09…