最近因为项目要求用c++,之前一直很讨厌c++,没办法只能短时间弥补c++的知识,项目中需要定义一个函数指针类型的vector,本以为很简单的问题,结果调试了一天,才发现错在哪里。
成都创新互联始终致力于在企业网站建设领域发展。秉承“创新、求实、诚信、拼搏”的企业精神,致力为企业提供全面的网络宣传与技术应用整体策划方案,为企业提供包括“网站建设、响应式网站建设、手机网站建设、微信网站建设、微信小程序开发、商城网站定制开发、平台网站建设秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。
先上代码吧,这里有一个测试代码,为什么要有测试代码?是因为下面的方式我在最开始验证该种实现时打印的地址是对的,但是之后一段时间就不对了,所以摘出来写了一个测试代码。
代码非常简单:使用using std::function的方式定义一个函数指针类型func_t,然后实现三个print函数,在main函数中定义一个vector存放三个函数的地址,打印三个函数的实际地址,之后遍历vector打印存放的元素值。
#include
#include
#include
// 定义 std::function 类型的函数指针别名
using func_t = std::function;
// 示例函数
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 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;
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
如果你也需要直接获取存储的函数指针的地址(C语言的习惯),最好还是直接使用原始的函数指针,而不是通过 std::function 来存储和获取函数指针的地址。
新闻标题:让人压抑的 C++:记一个函数指针的问题
URL地址:http://www.mswzjz.cn/qtweb/news42/20642.html
攀枝花网站建设、攀枝花网站运维推广公司-贝锐智能,是专注品牌与效果的网络营销公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 贝锐智能