C++ 怎么定义函数指针 C++ typedef与using定义回调函数类型【语法】
发布时间 - 2026-01-31 00:00:00 点击率:次函数指针是存储函数入口地址的变量,定义需严格匹配返回类型、参数列表及限定符(如const/noexcept/调用约定);推荐using定义回调类型,支持模板别名且可读性高。
怎么写一个指向函数的指针变量
函数指针本质是变量,它存储的是函数的入口地址,不是函数本身。定义时必须和目标函数的返回类型、参数个数与类型完全一致。
比如有函数 int add(int a, int b),它的函数指针类型是 int (*)(int, int);声明变量就得写成:
int (*func_ptr)(int, int) = add;
注意括号不能省:int *func_ptr(int, int) 是函数声明(返回 int*),不是函数指针。
常见错误:
- 漏掉最外层括号,导致被解析为函数声明
- 参数类型写错,比如把
const std::string&写成std::string,编译失败 - 用
auto推导时忘记加&或*,比如auto p = &add正确,auto p = add会退化为函数类型而非指针
typedef 和 using 哪个更适合定义回调类型
using 更推荐——语法更直观、支持模板别名、可读性高;typedef 在复杂声明里容易绕晕人,尤其嵌套函数指针时。
对比定义同一类型:
typedef int (*callback_t)(double, const char*);
using callback_t = int (*)(double, const char*);
两者等价,但 using 的等号形式更贴近“变量赋值”直觉,且能轻松扩展为模板别名:
template
using handler_t = void (*)(T, bool);
handler_th1 = [](int x, bool ok) { /* ... */ }; // OK
typedef 无法直接做这种泛型绑定。
定义带 const / noexcept / 引用限定符的函数指针类型
如果目标函数带 noexcept、const 成员限定或右值引用限定,函数指针类型也必须严格匹配,否则编译报错。
例如类成员函数:
struct Foo {
void method() const noexcept { }
};
void (Foo::*ptr)() const noexcept = &Foo::method;普通函数若声明为 void f() noexcept,其指针类型就是

void (*)() noexcept;漏掉 noexcept 就不兼容。
关键点:
- 成员函数指针必须用
ClassName::*语法,且要带上const/volatile/&/&&限定符 - 普通函数的
noexcept是类型系统一部分,不是修饰符,必须写在函数指针声明里 - C++17 起,函数类型中的
noexcept影响重载决议和模板推导
回调函数类型定义中容易忽略的 ABI 兼容问题
Windows 上 __stdcall、__cdecl 等调用约定是类型的一部分。用错会导致栈损坏或崩溃,但编译器不一定报错。
例如 Win32 API 的 WNDPROC 实际是:
using WNDPROC = LRESULT (CALLBACK*)(HWND, UINT, WPARAM, LPARAM);
其中 CALLBACK 展开为 __stdcall。如果你用 using my_proc = LRESULT (*)(HWND, UINT, WPARAM, LPARAM)(默认 __cdecl)去赋值,运行时可能 crash。
所以:
- 跨平台库尽量避免显式调用约定,依赖默认
- 对接系统 API 时,务必查文档确认调用约定,并在类型定义中显式写出(如
__stdcall) - Clang/GCC 下可用
__attribute__((stdcall))模拟,MSVC 下用__stdcall
函数指针的“类型安全”比看起来更脆弱——差一个 const、一个 noexcept、一个调用约定,都可能导致未定义行为,而编译器有时只给弱警告。
# windows
# 回调函数
# 栈
# c++
# win
# typedef
# String
# 成员函数
# const
# auto
# int
# void
# volatile
# 指针
# using
# 指针类型
# 泛型
# 回调
# 报错
# 的是
# 性高
# 就不
# 如有
# 并在
# 就得
# 而非
# 你用
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
JS中对数组元素进行增删改移的方法总结
关于BootStrap modal 在IOS9中不能弹出的解决方法(IOS 9 bootstrap modal ios 9 noticework)
使用Dockerfile构建java web环境
如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】
如何选择可靠的免备案建站服务器?
Laravel如何实现数据导出到CSV文件_Laravel原生流式输出大数据量CSV【方案】
惠州网站建设制作推广,惠州市华视达文化传媒有限公司怎么样?
Gemini怎么用新功能实时问答_Gemini实时问答使用【步骤】
php做exe能调用系统命令吗_执行cmd指令实现方式【详解】
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
黑客入侵网站服务器的常见手法有哪些?
HTML透明颜色代码怎么让下拉菜单透明_下拉菜单透明背景指南【技巧】
Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南
百度输入法ai组件怎么删除 百度输入法ai组件移除工具
韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐
Android 常见的图片加载框架详细介绍
奇安信“盘古石”团队突破 iOS 26.1 提权
Python制作简易注册登录系统
Laravel项目怎么部署到Linux_Laravel Nginx配置详解
详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南
Laravel怎么进行数据库回滚_Laravel Migration数据库版本控制与回滚操作
Laravel如何安装Breeze扩展包_Laravel用户注册登录功能快速实现【流程】
如何在 Pandas 中基于一列条件计算另一列的分组均值
如何快速选择适合个人网站的云服务器配置?
详解jQuery中的事件
实例解析angularjs的filter过滤器
合肥制作网站的公司有哪些,合肥聚美网络科技有限公司介绍?
如何用PHP快速搭建CMS系统?
在centOS 7安装mysql 5.7的详细教程
如何快速上传自定义模板至建站之星?
如何基于云服务器快速搭建网站及云盘系统?
Laravel如何实现多级无限分类_Laravel递归模型关联与树状数据输出【方法】
Laravel如何使用模型观察者?(Observer代码示例)
Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】
Laravel任务队列怎么用_Laravel Queues异步处理任务提升应用性能
公司网站制作价格怎么算,公司办个官网需要多少钱?
Laravel怎么创建控制器Controller_Laravel路由绑定与控制器逻辑编写【指南】
C语言设计一个闪闪的圣诞树
如何在 Telegram Web View(iOS)中防止键盘遮挡底部输入框
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
微信小程序 wx.uploadFile无法上传解决办法
如何打造高效商业网站?建站目的决定转化率
Laravel如何记录日志_Laravel Logging系统配置与自定义日志通道
Win11怎么恢复误删照片_Win11数据恢复工具使用【推荐】
购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?
如何快速查询网址的建站时间与历史轨迹?
EditPlus中的正则表达式 实战(4)
Laravel怎么发送邮件_Laravel Mail类SMTP配置教程
canvas 画布在主流浏览器中的尺寸限制详细介绍
Android实现代码画虚线边框背景效果

