当前位置: 首页 > news >正文

指针函数、函数指针和指针函数指针的全面总结

C++中指针函数、函数指针和指针函数指针的全面总结

一、核心概念区别

概念本质声明示例核心特征
指针函数返回指针的函数int* func(int);函数定义,返回值是指针类型
函数指针指向函数的指针int (*ptr)(int);变量,存储函数地址
指针函数指针指向指针函数的指针int* (*ptr)(int);指针,指向返回指针的函数

二、详细解析与C++现代替代方案

1. 指针函数(Pointer-Returning Function)

传统形式

int* createInt(int val) {
    return new int(val);
}

现代C++替代方案

// 使用智能指针
std::unique_ptr<int> createInt(int val) {
    return std::make_unique<int>(val);
}

// 工厂函数示例
class Widget {};
std::shared_ptr<Widget> createWidget() {
    return std::make_shared<Widget>();
}

优势

  • 自动内存管理
  • 异常安全
  • 明确所有权语义

2. 函数指针(Function Pointer)

传统形式

int add(int a, int b) { return a + b; }
int (*operation)(int, int) = &add;

// 使用
int result = operation(3, 4);

现代C++替代方案

// 使用std::function
#include <functional>
std::function<int(int, int)> op = [](int a, int b) { return a + b; };

// 使用模板
template<typename F>
void applyOperation(F&& f) {
    f(3, 4);
}

// Lambda表达式
auto multiply = [](int a, int b) { return a * b; };

对比优势

  • 支持lambda和函数对象
  • 类型更安全
  • 可存储状态(捕获上下文)
  • 更易读的语法

3. 指针函数指针(Pointer to Pointer-Returning Function)

传统形式

int* createArray(size_t size) {
    return new int[size];
}

int* (*arrayCreator)(size_t) = &createArray;

// 使用
int* arr = arrayCreator(10);

现代C++替代方案

// 使用智能指针和类型别名
using ArrayCreator = std::unique_ptr<int[]>(*)(size_t);
ArrayCreator creator = [](size_t size) { 
    return std::make_unique<int[]>(size); 
};

// 或使用std::function
std::function<std::unique_ptr<int[]>(size_t)> creator;

三、现代C++最佳实践总结

  1. 内存管理

    • 优先使用unique_ptr/shared_ptr
    • 避免裸指针所有权传递
  2. 回调机制

    // 传统(不推荐)
    void registerCallback(void (*callback)(int));
    
    // 现代(推荐)
    void registerCallback(std::function<void(int)> callback);
    
  3. 类型简化技巧

    // 复杂指针类型使用别名
    using ComplexHandler = void (*)(int*, const std::string&);
    
    // C++11后更推荐
    using SmartHandler = std::function<void(std::unique_ptr<int>, std::string_view)>;
    
  4. 成员函数处理

    // 传统成员函数指针
    void (MyClass::*memFunc)(int) = &MyClass::method;
    
    // 现代替代方案
    auto lambda = [obj = MyClass()](int x) { obj.method(x); };
    std::bind(&MyClass::method, &obj, std::placeholders::_1);
    

四、何时仍需使用传统形式

  1. 与C API交互时

    // qsort等C库函数需要的回调
    extern "C" void qsort(void*, size_t, size_t, int (*)(const void*, const void*));
    
  2. 极度性能敏感场景

    • 函数指针比std::function调用开销略低
  3. 嵌入式/系统级编程

    • 需要直接操作硬件地址时
  4. 模板元编程

    template<typename T, T (*Allocator)(size_t)>
    class CustomContainer { /*...*/ };
    

五、典型过渡示例

传统代码现代C++代码

// 传统
float* processData(int (*filter)(float), size_t size) {
    float* result = new float[size];
    // 处理...
    return result;
}

// 现代
std::unique_ptr<float[]> processData(
    std::function<int(float)> filter, 
    size_t size
) {
    auto result = std::make_unique<float[]>(size);
    // 处理...
    return result;
}

六、总结对比表

维度传统形式现代C++替代方案优势比较
返回值裸指针智能指针自动内存管理,异常安全
回调函数指针std::function/lambda更灵活,支持状态捕获
可读性复杂声明类型别名+auto代码更清晰
类型安全弱类型强类型系统编译期检查更严格
扩展性仅支持普通函数支持所有可调用对象兼容函数对象、成员函数等

现代C++不是要完全抛弃这些底层概念,而是提供更高层次的抽象,让开发者可以:

  1. 在需要控制底层时仍能使用传统方式
  2. 在大多数应用开发中使用更安全、更易用的替代方案
  3. 平滑过渡旧代码到现代实践

理解这些底层概念仍然很重要,它们是学习高级抽象的基础,也是处理特定场景的必要工具。

相关文章:

  • MySQL表缺乏主键或唯一索引对主从复制的深度影响及解决方案
  • linux课程学习三——静态/动态库的创建
  • 使用无人机进行露天矿运输道路分析
  • js中三元表达式(条件运算符)的用法总结
  • VCP考试通过率低?
  • vs2022中使用spdlog、C++日志
  • 时序数据库 InfluxDB(五)
  • 文件分享系统--开源的可视化文件共享管理工具
  • LeetCode 438. 找到字符串中所有字母的异位词
  • 9、tlm 事务交互通信
  • 【11408学习记录】破译语言密码·征服数学迷宫——长难句拆解与方程不等式全析
  • RK3588使用笔记:系统算法依赖库安装
  • Linux信号——信号的产生(1)
  • 自然语言处理(18:(第五章3.)LSTM的实现)
  • 【算法1-5】贪心
  • 一文详解VS2022配置LibTorch环境:Windows平台LibTorch CUDA与cuDNN开发环境配置
  • marked库(高效将 Markdown 转换为 HTML 的利器)
  • 算法训练营第二十九天 | 动态规划(二)
  • TS 中 keyof 和 in 关键字详解
  • 使用Vscode的Remote-SSH通过ssh密钥免输入密码连接远程服务器
  • 体育设施建设发布有没有网站/百度在线客服系统
  • 论坛类网站建站/国外常用的seo站长工具
  • 怎么把在微企点做响应式网站/私域流量运营管理
  • 可以做试题的网站/培训机构网站制作
  • 可编辑wordpress主题/长春关键词优化公司
  • 西安建设市场诚信信息平台网站/怎么做品牌推广和宣传