【C++】C++函數指針詳解與實用技巧

C++函數指針詳解與實用技巧

在C++中,**函數指針(Function Pointer)**是一種強大而靈活的工具,常用于回調機制、策略模式、事件處理等場景。本文將從概念、語法、常見用法到實戰示例,帶你全面掌握C++函數指針。


🧠 什么是函數指針?

函數指針本質上是一個指針,它指向一個函數的入口地址,就像普通指針指向內存中的數據一樣。

例如,一個函數如下:

int add(int a, int b) {return a + b;
}

我們可以定義一個指針,指向這個函數,然后通過指針來調用它。


🧱 函數指針的基本語法

函數指針的定義語法有點繞,但遵循以下模板就能掌握:

返回類型 (*指針變量名)(參數類型列表);

add 為例,它的函數指針定義如下:

int (*funcPtr)(int, int);  // 聲明函數指針
funcPtr = add;             // 指向函數
int result = funcPtr(3, 4);  // 調用函數

💡 注意:函數名本身就是指向函數的指針,add&add 等價。


🧩 函數指針的常見用途

1?? 替代 if-else/switch:簡化邏輯選擇

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }int main() {int (*op)(int, int);char choice = '+';if (choice == '+') op = add;else if (choice == '-') op = sub;std::cout << "Result: " << op(10, 5) << std::endl;
}

2?? 作為函數參數(回調機制)

void process(int a, int b, int (*op)(int, int)) {std::cout << "Result: " << op(a, b) << std::endl;
}int add(int a, int b) { return a + b; }int main() {process(3, 4, add);
}

3?? 返回函數指針(高級用法)

int multiply(int a, int b) { return a * b; }int (*getOperation())(int, int) {return multiply;
}int main() {auto op = getOperation();std::cout << "Result: " << op(6, 7) << std::endl;
}

4?? 使用數組存儲多個函數指針(策略切換)

int add(int a, int b) { return a + b; }
int sub(int a, int b) { return a - b; }
int mul(int a, int b) { return a * b; }int main() {int (*ops[3])(int, int) = { add, sub, mul };int choice = 2;  // 使用第3個函數(mul)std::cout << "Result: " << ops[choice](3, 5) << std::endl;
}

🧼 函數指針 vs std::function

在現代C++中,推薦使用 std::function 來代替裸函數指針,它更安全,能包裝函數、Lambda表達式、成員函數等:

#include <functional>std::function<int(int, int)> op = [](int a, int b) {return a * b;
};
std::cout << op(4, 5);  // 輸出 20

🚀 如果你用的是 C++11 及以上版本,請優先考慮 std::functionLambda 表達式。


🧭 總結

特性描述
本質指向函數地址的指針
作用支持回調機制、動態策略選擇
使用難點語法略顯復雜,注意括號位置
推薦替代方案std::function、Lambda 表達式

函數指針雖在現代C++中使用頻率下降,但在系統編程、嵌入式開發、回調機制等場景中仍有不可替代的價值。


📌 提問環節

QT中在connect函數中,第二參數使用了&對函數進行取地址,是否是多此一舉呢?

答案是:不,多此一舉——是必要的“好習慣”或“為了清晰性”


👇 來看這個典型用法:

QObject::connect(button, &QPushButton::clicked, this, &MyClass::onButtonClicked);

🤔 &QPushButton::clicked 為什么還要加 &,難道 QPushButton::clicked 本身不是函數指針嗎?


? 理論上:是的,確實可以不加 &

在C++中,函數名本身就可以衰變(decay)為指針。也就是說,這樣寫:

QObject::connect(button, QPushButton::clicked, this, MyClass::onButtonClicked);

在部分情況下也能通過編譯,但在 Qt 的宏系統(尤其是舊版本或使用 Qt 元對象編譯器 moc 的語法檢查)中,會產生二義性、模糊錯誤或編譯失敗。


? 實際上:加 & 更清晰、更兼容、更安全

  • 明確表示取地址,避免閱讀歧義
  • 支持 Qt5/Qt6 的 lambda、函數指針、重載函數等一致寫法
  • 對有重載信號的類,比如 QComboBox::activated,必須用 & 明確指定版本

? 舉例(必須使用 & 才能工作):

QObject::connect(comboBox,static_cast<void (QComboBox::*)(int)>(&QComboBox::activated),this,&MyClass::onIndexChanged);

🔔 小結:

寫法是否能編譯是否推薦說明
&QPushButton::clicked??明確、兼容、推薦
QPushButton::clicked?/???可能模糊,非標準,易錯

? 結論:加 & 雖然在某些情況下是“多余”的,但為了兼容性和代碼清晰性,絕不是多此一舉,反而是推薦做法。

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

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

相關文章

【計算機視覺】基于深度學習的實時情緒檢測系統:emotion-detection項目深度解析

基于深度學習的實時情緒檢測系統&#xff1a;emotion-detection項目深度解析 1. 項目概述2. 技術原理與模型架構2.1 核心算法1) 數據預處理流程2) 改進型MobileNetV2 2.2 系統架構 3. 實戰部署指南3.1 環境配置3.2 數據集準備3.3 模型訓練3.4 實時推理 4. 常見問題與解決方案4.…

IC ATE集成電路測試學習——電流測試的原理和方法

電流測試 我們可以通過電流來判斷芯片的工作狀態時&#xff0c;首先先了解下芯片的電流是如何產生的。 靜態電流 理論上&#xff0c;CMOS結構的芯片靜態時幾乎不耗電 CMOS基本結構&#xff1a;Pmos Nmos 串聯當邏輯電平穩定時&#xff1a; ? 要么Pmos導通&#xff0c;Nmo…

stm32week15

stm32學習 十一.中斷 2.NVIC Nested vectored interrupt controller&#xff0c;嵌套向量中斷控制器&#xff0c;屬于內核(M3/4/7) 中斷向量表&#xff1a;定義一塊固定的內存&#xff0c;以4字節對齊&#xff0c;存放各個中斷服務函數程序的首地址&#xff0c;中斷向量表定…

list類的詳細講解

【本節目標】 1. list的介紹及使用 2. list的深度剖析及模擬實現 3. list與vector的對比 1. list的介紹及使用 1.1 list的介紹 1. list 是可以在常數范圍內在任意位置進行插入和刪除的序列式容器&#xff0c;并且該容器可以前后雙向迭代。 2. list 的底層是雙向鏈表結構&a…

第十節:圖像處理基礎-圖像算術運算 (加法、減法、混合)

引言 在計算機視覺領域,圖像算術運算是最基礎卻至關重要的核心技術。無論是實現簡單的圖片合成、開發智能監控系統,還是構建復雜的醫學影像分析工具,加減運算和混合操作都扮演著關鍵角色。OpenCV作為最流行的計算機視覺庫,提供了完善的圖像處理函數集。本文將深入解析三種…

【React 的useState鉤子詳解】

React 的 useState 鉤子詳解 useState 是 React 中最基礎且最常用的 Hook 之一&#xff0c;它允許你在函數組件中添加和管理狀態。 基本語法 const [state, setState] useState(initialState);initialState: 狀態的初始值&#xff0c;可以是任何 JavaScript 數據類型state:…

vue 中的數據代理

在 Vue 中&#xff0c;數據代理&#xff08;Data Proxy&#xff09; 是 Vue 實現 MVVM 模式 的關鍵技術之一。Vue 使用數據代理讓你可以通過 this.message 訪問 data.message&#xff0c;而不需要寫 this.data.message —— 這大大簡化了模板和邏輯代碼。 我們來深入理解它的本…

基于Python的網絡電子書閱讀系統

標題:基于Python的網絡電子書閱讀系統 內容:1.摘要 隨著數字化閱讀的興起&#xff0c;網絡電子書閱讀需求日益增長。本研究旨在開發一個基于Python的網絡電子書閱讀系統&#xff0c;以滿足用戶便捷閱讀電子書的需求。采用Python的Flask框架搭建Web服務器&#xff0c;結合SQLit…

基于SpringBoot的抽獎系統測試報告

一、編寫目的 本報告為抽獎系統測試報告&#xff0c;本項目可用于團體抽獎活動&#xff0c;包括了用戶注冊&#xff0c;用戶登錄&#xff0c;修改獎項以及抽獎等功能。 二、項目背景 抽獎系統采用前后端分離的方法來實現&#xff0c;同時使用了數據庫來存儲相關的數據&…

Apache Flink 與 Flink CDC:概念、聯系、區別及版本演進解析

Apache Flink 與 Flink CDC:概念、聯系、區別及版本演進解析 在實時數據處理和流式計算領域,Apache Flink 已成為行業標桿。而 Flink CDC(Change Data Capture) 作為其生態中的重要組件,為數據庫的實時變更捕獲提供了強大的能力。 本文將從以下幾個方面進行深入講解: 什…

單片機-STM32部分:9、定時器

飛書文檔https://x509p6c8to.feishu.cn/wiki/A749wx8T0ioqfgkzZKlc9poknUf SMT32F1系列共有8個定時器&#xff1a; 基本定時器&#xff08;TIM6、TIM7&#xff09; 通用定時器&#xff08;TIM2、TIM3、TIM4、TIM5&#xff09; 高級定時器&#xff08;TIM1、TIM8&#xff09…

uniapp-商城-51-后臺 商家信息(logo處理)

前面對頁面基本進行了梳理和說明&#xff0c;特別是對驗證規則進行了闡述&#xff0c;并對自定義規則的兼容性進行了特別補充&#xff0c;應該說是干貨滿滿。不知道有沒有小伙伴已經消化了。 下面我們繼續前進&#xff0c;說說頁面上的logo上傳組件&#xff0c;主要就是uni-fil…

ideal創建Springboot項目(Maven,yml)

以下是使用 IntelliJ IDEA 創建基于 Maven 的 Spring Boot 項目并使用 YAML 配置文件的詳細步驟&#xff1a; 一、創建 Spring Boot 項目 啟動項目創建向導 打開 IntelliJ IDEA&#xff0c;點擊“File”->“New”->“Project”。 在彈出的“New Project”窗口中&#…

MATLAB中矩陣和數組的區別

文章目錄 前言環境配置1. 數據結構本質2. 運算規則&#xff08;1&#xff09;基本運算&#xff08;2&#xff09;特殊運算 3. 函數與操作4. 高維支持5. 創建方式 前言 在 MATLAB 中&#xff0c;矩陣&#xff08;Matrix&#xff09; 和 數組&#xff08;Array&#xff09; 的概…

iTwin 數據報表(只是簡單的原型不代表實現)

大概想法是 前端從schema和class中選中感興趣的property內容生成ecsql語句傳遞給后端后端解析ecsql并提供公開接口給各個分析工具&#xff0c;如excel&#xff0c;poewerBI等&#xff08;Odata或者直接選擇來自網站&#xff09;再由分析工具做進一步的處 還未想好的點 如何存…

Spring AI 系列——使用大模型對文本內容分類歸納并標簽化輸出

原理概述 利用大語言模型&#xff08;LLM&#xff09;實現文本分類&#xff0c;核心思想是通過預訓練模型理解輸入文本的語義&#xff0c;并將其映射到預先定義好的分類標簽。在這個過程中&#xff0c;我們借助 Spring AI Alibaba 提供的能力&#xff0c;使用阿里云 DashScope…

LeetCode 高頻題實戰:如何優雅地序列化和反序列化字符串數組?

文章目錄 摘要描述題解答案題解代碼分析編碼方法解碼方法 示例測試及結果時間復雜度空間復雜度總結 摘要 在分布式系統中&#xff0c;數據的序列化與反序列化是常見的需求&#xff0c;尤其是在網絡傳輸、數據存儲等場景中。LeetCode 第 271 題“字符串的編碼與解碼”要求我們設…

GitHub打開緩慢甚至失敗的解決辦法

在C:\Windows\System32\drivers\etc的hosts中增加如下內容&#xff1a; 20.205.243.166 github.com 199.59.149.236 github.global.ssl.fastly.net185.199.109.153 http://assets-cdn.github.com 185.199.108.153 http://assets-cdn.github.com 185.199.110.153 http://asset…

重生之我在2024學Fine-tuning

一、Fine-tuning&#xff08;微調&#xff09;概述 Fine-tuning&#xff08;微調&#xff09;是機器學習和深度學習中的一個重要概念&#xff0c;特別是在預訓練模型的應用上。它指的是在模型已經通過大量數據訓練得到一個通用的預訓練模型后&#xff0c;再針對特定的任務或數據…

計算機網絡 4-2-1 網絡層(IPv4)

2 IPv4分組 各協議之間的關系 IP協議(Internet Protocol, 網際協議)是互聯網的核心&#xff01; ARP協議用于查詢同一網絡中的<主機IP地址&#xff0c;MAC地址>之間的映射關系 ICMP協議用于網絡層實體之間相互通知“異常事件” IGMP協議用于實現IP組播 2.1 結構<首…