成人免费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++接口

2023-11-22 13:22:51

C++函數

2011-04-11 11:09:50

this指針

2024-07-03 12:04:42

C++this?

2021-05-28 18:12:51

C++設計

2011-07-20 17:54:02

C++

2021-06-18 12:30:36

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++編程開發

2025-05-20 08:10:00

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

2010-01-18 15:53:27

C++析構函數

2021-01-13 06:58:35

C語言函數指針

2010-02-06 09:31:42

C++函數對象

2011-04-19 16:38:00

對象指針指針C++

2011-07-15 01:38:56

C++this指針

2011-04-19 09:19:09

C++指針
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日本三级电影在线观看视频 | 日韩三级电影一区二区 | 日韩二 | 奇米久久 | av一区在线观看 | 九九热这里 | 亚洲成年人免费网站 | 日韩第一区 | 91精品国产综合久久久久久 | 日韩综合在线 | 成人av一区二区三区 | 91国在线观看 | 免费观看成人鲁鲁鲁鲁鲁视频 | 欧美在线国产精品 | 精品国产一区二区久久 | 在线看av网址 | 国产免费一区二区三区 | 精品国产91 | 在线婷婷| 日韩国产精品一区二区三区 | 亚洲导航深夜福利涩涩屋 | 神马九九 | 日韩中文字幕免费在线观看 | 亚洲视频在线看 | 亚洲在线看 | 婷婷综合五月天 | 日韩成人av在线 | 污免费网站 | 欧美在线一区二区三区 | 91精品成人久久 | 欧美aⅴ片 | 欧美日韩在线观看视频 | 国产精品亚洲精品日韩已方 | 免费一级片 | 一本色道久久综合亚洲精品高清 | 久久精品在线播放 | 久久综合伊人 | 国产精品久久 | 中文字幕亚洲一区 | 亚洲精品国产第一综合99久久 | 国产精品视屏 |