c++如何定义指向函数的指针_c++函数指针语法【核心】

3次阅读

函数指针正确声明为int (*func_ptr)(int, int),星号与名称必须括起;赋值时函数名自动退化为指针;调用前须判空并确保签名严格匹配;std::function用于Lambda成员函数等灵活场景,原生指针适用于高性能确定场景。

c++如何定义指向函数的指针_c++函数指针语法【核心】

函数指针声明怎么写才不报错

最常出错的是括号位置——int (*func_ptr)(int, int) 是对的,int *func_ptr(int, int) 是错的(这其实是函数声明,返回 int*)。关键在星号和函数名必须用括号包住,否则编译器按优先级解析成“返回指针的函数”。

  • 左边类型是函数返回值(如 int),右边是参数列表(如 (int, int)),中间 (*func_ptr) 表明这是个指针
  • 如果函数有 const 限定符或引用参数,也要原样写进去,比如 void (*cb)(const std::String&)
  • 使用 typedefusing 可读性更高:using cmp_func = bool (*)(int, int);

怎么把函数名赋给函数指针

函数名本身会自动退化为函数指针,不需要加取地址符 &(加了也不报错,但冗余)。但注意:只能赋值「非重载、非模板、非成员」的普通函数。

  • 正确:int add(int a, int b) { return a + b; } cmp_func p = add;
  • 错误:p = std::max;(模板函数不能直接取地址)
  • 错误:p = obj.method;(非静态成员函数有隐式 this 参数,类型不匹配)
  • 若真要存成员函数,得用 std::function 或带对象指针的绑定方式

调用函数指针时常见崩溃原因

崩溃往往不是语法问题,而是调用时指针为空或类型不匹配。c++ 不检查函数指针的实际签名,一旦传错参数个数或类型,行为未定义。

  • 务必初始化指针:int (*fp)(int) = nullptr;,调用前判空
  • 参数类型严格匹配:double(*)(Float)double(*)(double) 是不同类型,不能混用
  • 调用语法有两种等价写法:fp(42)(*fp)(42),前者更常用,但别误写成 fp[0](42) 这类数组访问
  • 若函数有可变参数(如 printf 风格),函数指针无法安全表达,应避免

std::function 替代原生函数指针的时机

原生函数指针轻量、零开销,但太僵硬;std::function 灵活但带小开销(可能分配、虚调用)。是否切换,看实际需求。

立即学习C++免费学习笔记(深入)”;

  • 需要存 lambda(尤其捕获变量)、成员函数、bind 表达式时,必须用 std::function
  • 做回调接口且使用者可能传各种 callable 时,std::function 更友好
  • 高频调用(如图形渲染循环里每帧调用)且确定只传普通函数,坚持用原生指针
  • std::function 构造失败会抛 std::bad_function_call,而原生指针解引用空值直接 UB

函数指针的语法容错率低,一个括号位置错就完全变义;更麻烦的是,类型不匹配在编译期未必报错,运行时才崩。所以定义时多盯两眼括号,赋值时确认函数签名一字不差,比事后调试省太多事。

text=ZqhQzanResources