成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

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

開發 前端
如果你也需要直接獲取存儲的函數指針的地址,最好還是直接使用原始的函數指針,而不是通過 std::function 來存儲和獲取函數指針的地址。?

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

多余的std::function

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

代碼非常簡單:使用using std::function的方式定義一個函數指針類型func_t,然后實現三個print函數,在main函數中定義一個vector存放三個函數的地址,打印三個函數的實際地址,之后遍歷vector打印存放的元素值。


#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;
}

執行后的結果:

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

我嘗試切換一種函數指針定義,使用我最原始的方式:

// 定義 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*);

運行后發現這次是對的了:

最后經過一番查找,得出結論如下:

實際上,std::function 存儲函數指針時,不直接存儲函數指針本身的地址,而是存儲了函數指針對象的一些信息,因此直接使用 %x 來打印 std::function 存儲的函數指針可能無法獲得正確的地址。

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

由于 std::function 對象的內部結構不同于原始函數指針, std::function 對象存儲了更多的信息,所以直接打印 std::function 對象的地址并不會得到和原始函數指針相同的值,打印它的地址并不等同于打印函數指針的地址。

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

那為什么打印的值一樣呢?

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

總結

如果你也需要直接獲取存儲的函數指針的地址(C語言的習慣),最好還是直接使用原始的函數指針,而不是通過 std::function 來存儲和獲取函數指針的地址。

責任編輯:趙寧寧 來源: 囧囧妹
相關推薦

2021-06-16 17:46:55

函數指針結構

2011-04-11 14:18:37

CC++指針

2023-11-21 21:59:50

c++接口

2011-04-11 11:09:50

this指針

2023-11-22 13:22:51

C++函數

2024-07-03 12:04:42

C++this?

2021-05-28 18:12:51

C++設計

2021-06-18 12:30:36

C++函數指針編程語言

2011-07-20 17:54:02

C++

2014-01-24 09:49:01

C++指針

2011-07-14 17:02:09

C++指針

2018-01-29 21:56:28

Bug程序程序員

2024-05-15 16:01:04

C++編程開發

2021-01-13 06:58:35

C語言函數指針

2025-05-20 08:10:00

函數函數類型函數指針類型

2010-01-18 15:53:27

C++析構函數

2011-04-19 16:38:00

對象指針指針C++

2011-07-15 01:38:56

C++this指針

2011-04-19 09:19:09

C++指針

2010-02-06 09:31:42

C++函數對象
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 成人h动漫亚洲一区二区 | 亚洲精品国产成人 | 女同久久 | 粉嫩一区二区三区性色av | 欧美激情综合 | 欧美精品乱码久久久久久按摩 | 91在线精品秘密一区二区 | 久久久久久国产精品免费免费 | 久久大陆 | 成人国产精品久久久 | 成人国产在线视频 | 精品一区二区三区入口 | 色综合久 | 高清视频一区二区三区 | 男女羞羞视频网站 | 二区三区视频 | 精品国产一区二区久久 | 很很干很很日 | 日日日操 | 亚洲国产精品久久 | av天天看 | 精品一区二区三区在线观看 | 中文字幕久久精品 | 毛片在线看片 | 热久色| 中文字幕国产在线 | 亚洲1区 | 999久久久久久久久6666 | 日韩免费在线观看视频 | 成人在线视频观看 | 日韩精品一区二区三区中文字幕 | 国产精品不卡 | 色视频网站在线观看 | 久久视频精品 | 欧美精品一区二区三区蜜桃视频 | 亚洲欧美日韩精品久久亚洲区 | 欧美一区在线看 | 伊伊综合网 | 一区二区三区中文字幕 | 欧美日韩久久 | 99久久婷婷国产亚洲终合精品 |