日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

讓人壓抑的 C++:記一個函數指針的問題

來源: 責編: 時間:2023-11-28 17:12:00 239觀看
導讀最近因為項目要求用c++,之前一直很討厭c++,沒辦法只能短時間彌補c++的知識,項目中需要定義一個函數指針類型的vector,本以為很簡單的問題,結果調試了一天,才發現錯在哪里。多余的std::function先上代碼吧,這里有一個測試代碼

最近因為項目要求用c++,之前一直很討厭c++,沒辦法只能短時間彌補c++的知識,項目中需要定義一個函數指針類型的vector,本以為很簡單的問題,結果調試了一天,才發現錯在哪里。YiG28資訊網——每日最新資訊28at.com

YiG28資訊網——每日最新資訊28at.com

多余的std::function

先上代碼吧,這里有一個測試代碼,為什么要有測試代碼?是因為下面的方式我在最開始驗證該種實現時打印的地址是對的,但是之后一段時間就不對了,所以摘出來寫了一個測試代碼。YiG28資訊網——每日最新資訊28at.com

代碼非常簡單:使用using std::function的方式定義一個函數指針類型func_t,然后實現三個print函數,在main函數中定義一個vector存放三個函數的地址,打印三個函數的實際地址,之后遍歷vector打印存放的元素值。YiG28資訊網——每日最新資訊28at.com

#include <iostream>#include <vector>#include <functional>// 定義 std::function 類型的函數指針別名using func_t = std::function<void(int, void*, size_t, size_t, void*)>;// 示例函數void print(int x, void* y, size_t a, size_t b, void* c) {    std::cout << "print hello/n";}void print1(int x, void* y, size_t a, size_t b, void* c) {    std::cout << "print1 hello/n";}void print2(int x, void* y, size_t a, size_t b, void* c) {    std::cout << "print2 hello/n";}int main() {    // 創建一個存儲 std::function 類型的函數指針對象的 std::vector    std::vector<func_t> vec;    // 使用 push_back 將函數指針對象添加到 std::vector 中    vec.push_back(print);    vec.push_back(print1);    vec.push_back(print2);    printf("%x, %x, %x/n", print, print1, print2);    // 遍歷 std::vector 并依次調用存儲的函數指針對象    for (const auto& func : vec) {        // 調用函數指針對象        //func(0, nullptr, 0, 0, nullptr);        printf("%x./n", func);    }    return 0;}

執行后的結果:YiG28資訊網——每日最新資訊28at.com

YiG28資訊網——每日最新資訊28at.com

我最開始的理解是vector內部存放的地址就是三個函數的地址。結果打印的結果意料之外啊,居然一樣,我嘗試在for循環遍歷時執行該地址函數,結果還能正常運行。最開始以為是vector遍歷取值的問題,后來經過一番驗證沒問題,最后鎖定要函數指針定義上。YiG28資訊網——每日最新資訊28at.com

我嘗試切換一種函數指針定義,使用我最原始的方式:YiG28資訊網——每日最新資訊28at.com

// 定義 std::function 類型的函數指針別名//using func_t = std::function<void(int, void*, size_t, size_t, void*)>;using func_t = void (*)(int, void*, size_t, size_t, void*);

YiG28資訊網——每日最新資訊28at.com

運行后發現這次是對的了:YiG28資訊網——每日最新資訊28at.com

YiG28資訊網——每日最新資訊28at.com

YiG28資訊網——每日最新資訊28at.com

最后經過一番查找,得出結論如下:YiG28資訊網——每日最新資訊28at.com

實際上,std::function 存儲函數指針時,不直接存儲函數指針本身的地址,而是存儲了函數指針對象的一些信息,因此直接使用 %x 來打印 std::function 存儲的函數指針可能無法獲得正確的地址。YiG28資訊網——每日最新資訊28at.com

在標準庫 中,std::function 是一個函數包裝器,它可以包含各種可調用對象(函數指針、函數對象、成員函數指針、Lambda 表達式等)。因此,std::function 內部存儲了被包裝對象的地址以及其他信息,而不是直接將被包裝對象的地址暴露給用戶。YiG28資訊網——每日最新資訊28at.com

由于 std::function 對象的內部結構不同于原始函數指針, std::function 對象存儲了更多的信息,所以直接打印 std::function 對象的地址并不會得到和原始函數指針相同的值,打印它的地址并不等同于打印函數指針的地址。YiG28資訊網——每日最新資訊28at.com

所以,如果需要存儲函數指針并在之后通過 std::function 來調用它們,可以直接通過 std::function 來調用并且可以得到預期的結果,但是打印地址是不保證能夠得到和原始函數指針相同的地址(這也是我遇到了幾次和原始函數指針一致的時候,這也是造成我更迷茫的原因)。YiG28資訊網——每日最新資訊28at.com

YiG28資訊網——每日最新資訊28at.com

那為什么打印的值一樣呢?YiG28資訊網——每日最新資訊28at.com

因為在遍歷 std::vector<std::function> 時,即使它們指向不同的函數,它們的內部指針值可能是相同的,這是因為 std::function 可以包裝不同的可調用對象,但它們內部可能使用相同的機制來存儲函數指針或者函數對象的地址。因此,打印 std::function 內部存儲的函數指針值可能會得到相同的結果。但這不應該影響 std::function 執行其持有的不同函數的能力。YiG28資訊網——每日最新資訊28at.com

總結

YiG28資訊網——每日最新資訊28at.com

如果你也需要直接獲取存儲的函數指針的地址(C語言的習慣),最好還是直接使用原始的函數指針,而不是通過 std::function 來存儲和獲取函數指針的地址。YiG28資訊網——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-34923-0.html讓人壓抑的 C++:記一個函數指針的問題

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 大型直播活動保障S13的實踐和思考

下一篇: Istio新架構揭秘:環境化Mesh

標簽:
  • 熱門焦點
  • 鴻蒙OS 4.0公測機型公布:甚至連nova6都支持

    華為全新的HarmonyOS 4.0操作系統將于今天下午正式登場,官方在發布會之前也已經正式給出了可升級的機型產品,這意味著這些機型會率先支持升級享用。這次的HarmonyOS 4.0支持
  • K60 Pro官方停產 第三方瞬間漲價

    雖然沒有官方宣布,但Redmi的一些高管也已經透露了,Redmi K60 Pro已經停產且不會補貨,這一切都是為了即將到來的K60 Ultra鋪路,屬于廠家的正常操作。但有意思的是該機在停產之后
  • 十個可以手動編寫的 JavaScript 數組 API

    JavaScript 中有很多API,使用得當,會很方便,省力不少。 你知道它的原理嗎? 今天這篇文章,我們將對它們進行一次小總結。現在開始吧。1.forEach()forEach()用于遍歷數組接收一參
  • 企業采用CRM系統的11個好處

    客戶關系管理(CRM)軟件可以為企業提供很多的好處,從客戶保留到提高生產力。  CRM軟件用于企業收集客戶互動,以改善客戶體驗和滿意度。  CRM軟件市場規模如今超過580
  • 每天一道面試題-CPU偽共享

    前言:了不起:又到了每天一到面試題的時候了!學弟,最近學習的怎么樣啊 了不起學弟:最近學習的還不錯,每天都在學習,每天都在進步! 了不起:那你最近學習的什么呢? 了不起學弟:最近在學習C
  • 超級標準版旗艦!iQOO 11S全球首發iQOO超算獨顯芯片

    上半年已接近尾聲,截至目前各大品牌旗下的頂級旗艦都已悉數亮相,而下半年即將推出的頂級旗艦已經成為了數碼圈爆料的主流,其中就包括全新的iQOO 11S系
  • 由于成本持續增加,筆記本產品價格預計將明顯上漲

    根據知情人士透露,由于材料、物流等成本持續增加,筆記本產品價格預計將在2021年下半年有明顯上漲。進入6月下旬以來,全球半導體芯片缺貨情況加劇,顯卡、處理器
  • “買真退假” 這種“羊毛”不能薅

    □ 法治日報 記者 王春   □ 本報通訊員 胡佳麗  2020年初,還在上大學的小東加入了一個大學生兼職QQ群。群主&ldquo;七王&rdquo;在群里介紹一些刷單賺
  • 榮耀Magic4 至臻版 首創智慧隱私通話 強勁影音系統

    2022年第一季度臨近尾聲,在該季度內,許多品牌陸續發布自己的最新產品,讓大家從全新的角度來了解當今的手機技術。手機是電子設備中,更新迭代十分迅速的一款產品,基
Top 主站蜘蛛池模板: 桑植县| 隆化县| 绵阳市| 东辽县| 康马县| 宜良县| 马关县| 黔西县| 泰顺县| 景洪市| 师宗县| 库伦旗| 扎赉特旗| 五大连池市| 西乡县| 贵德县| 攀枝花市| 新巴尔虎左旗| 壤塘县| 西贡区| 攀枝花市| 通化县| 镇宁| 永德县| 隆德县| 三门峡市| 石门县| 玉田县| 苍南县| 印江| 桓台县| 小金县| 珠海市| 集安市| 农安县| 小金县| 德江县| 民勤县| 龙胜| 普洱| 辽中县|