C++函数指针与成员函数指针问题详解与解决方法

C++函数指针与成员函数指针问题详解与解决方法

1. 函数指针基本概念与问题

1.1 函数指针的类型复杂性

// 不同函数签名对应的函数指针类型
int normal_func(int, double);           // 普通函数
auto lambda = [](int, double) -> int;   // lambda表达式

// 对应的函数指针类型
int (*func_ptr1)(int, double) = &normal_func;  // 指向普通函数
int (*func_ptr2)(int, double) = lambda;        // 错误!lambda不是函数指针

// 使用typedef或using简化
typedef int (*FuncPtr)(int, double);           // C风格
using FuncPtr = int(*)(int, double);           // C++风格

// 问题:函数指针类型冗长且容易出错
void (*complex_ptr)(int (*)(int, int), const std::string&);
// 这是一个指向函数的指针,该函数接受两个参数:
// 1. 一个函数指针(指向返回int,接受两个int的函数)
// 2. 一个const std::string&

// 对应的using声明
using InnerFunc = int(*)(int, int);
using ComplexFunc = void(*)(InnerFunc, const std::string&);

1.2 函数指针的初始化与调用问题

int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }

void test_function_pointer_issues() {
    // 问题1:函数名会隐式转换为函数指针
    int (*ptr1)(int, int) = add;        // OK: 隐式转换
    int (*ptr2)(int, int) = &add;       // OK: 显式取地址
    
    // 问题2:调用时可以不解引用
    int result1 = ptr1(3, 4);           // OK: 直接调用
    int result2 = (*ptr1)(3, 4);        // OK: 解引用后调用
    int result3 = (****ptr1)(3, 4);     // 依然OK!多次解引用
    
    // 问题3:类型不匹配的隐式转换
    int (*ptr3)(int, int) = nullptr;    // OK: 空指针
    // int result4 = ptr3(3, 4);        // 运行时错误:空指针调用
    
    // 问题4:重载函数导致歧义
    void process(int);
    void process(double);
    
    // void (*p1)(int) = process;       // OK: 选择process(int)
    // void (*p2)(double) = process;    // OK: 选择process(double)
    // void (*p3)() = process;          // 错误:没有匹配的重载
    
    // 问题5:const/volatile限定符
    int const_func(const int) const;    // 成员函数,后面讨论
    // 对于非成员函数,参数上的const不影响函数指针类型
    int (*p4)(int) = const_func;        // OK: const int -> int是允许的
}

2. 成员函数指针的特殊问题

2.1 成员函数指针的基本语法

class MyClass {
public:
    int value;
    
    // 普通成员函数
    int add(int x) { return value + x; }
    
    // const成员函数
    int get_value() const { return value; }
    
    // 静态成员函数
    static int static_add(int a, int b) { return a + b; }
    
    // 虚函数
    virtual void virtual_func() { std::cout << "Base" << std::endl; }
};

void test_member_function_pointer() {
    MyClass obj;
    obj.value = 10;
    
    // 1. 普通成员函数指针
    int (MyClass::*mem_ptr)(int) = &MyClass::add;
    int result = (obj.*mem_ptr)(5);  // 调用 obj.add(5)
    
    // 2. const成员函数指针
    int (MyClass::*const_mem_ptr)() const = &MyClass::get_value;
    int val = (obj.*const_mem_ptr)();  // 调用 obj.get_value()
    
    // 3. 静态成员函数指针(与普通函数指针相同)
    int (*static_ptr)(int, int) = &MyClass::static_add;
    int sum = static_ptr(3, 4);  // 调用静态函数
    
    // 4. 虚函数指针
    void (MyClass::*virtual_ptr)() = &MyClass::virtual_func;
    (obj.*virtual_ptr)();  // 多态调用
    
    // 问题:语法极其冗长复杂!
}

2.2 继承体系中的成员函数指针

class Base {
public:
    virtual void func() { std::cout << "Base::func" << std::endl; }
    void non_virtual() { std::cout << "Base::non_virtual" << std::endl; }
};

class Derived : public Base {
public:
    void func() override { std::cout << "Derived::func" << std::endl; }
    void non_virtual() { std::cout << "Derived::non_virtual" << std::endl; }
};

void test_inheritance_issues() {
    // 1. 基类成员函数指针可以指向派生类对象
    void (Base::*base_ptr)() = &Base::func;
    
    Base base;
    Derived derived;
    
    (base.*base_ptr)();      // 输出: Base::func
    (derived.*base_ptr)();   // 输出: Derived::func (多态)
    
    // 2. 派生类成员函数指针不能指向基类对象
    void (Derived::*derived_ptr)() = &Derived::func;
    // (base.*derived_ptr)();  // 编译错误:基类没有派生类成员
    
    // 3. 非虚函数的行为
    void (Base::*non_virt_ptr)() = &Base::non_virtual;
    (base.*non_virt_ptr)();     // 输出: Base::non_virtual
    (derived.*non_virt_ptr)();  // 输出: Base::non_virtual (没有多态!)
    
    // 4. 成员函数指针的转换
    // 从派生类到基类的转换是允许的
    void (Base::*converted_ptr)() = static_cast<void (Base::*)()>(&Derived::func);
    // 但反过来不行
}

2.3 多继承中的成员函数指针问题

class Base1 {
public:
    virtual void f1() { std::cout << "Base1::f1" << std::endl; }
    int x;
};

class Base2 {
public:
    virtual void f2() { std::cout << "Base2::f2" << std::endl; }
    int y;
};

class Derived : public Base1, public Base2 {
public:
    void f1() override { std::cout << "Derived::f1" << std::endl; }
    void f2() override { std::cout << "Derived::f2" << std::endl; }
};

void test_multiple_inheritance() {
    Derived d;
    
    // 1. 不同基类的成员函数指针大小可能不同!
    void (Base1::*b1_ptr)() = &Base1::f1;
    void (Base2::*b2_ptr)() = &Base2::f2;
    
    std::cout << "Size of Base1::*: " << sizeof(b1_ptr) << std::endl;
    std::cout << "Size of Base2::*: " << sizeof(b2_ptr) << std::endl;
    // 在多继承中,成员函数指针可能需要存储额外的信息来调整this指针
    
    // 2. 通过派生类调用
    (d.*b1_ptr)();  // 输出: Derived::f1
    (d.*b2_ptr)();  // 输出: Derived::f2
    
    // 3. 转换问题
    // void (Derived::*d_ptr)() = &Derived::f1;  // 哪个f1?有歧义
    void (Derived::*d_f1_ptr)() = static_cast<void (Derived::*)()>(&Base1::f1);
    void (Derived::*d_f2_ptr)() = static_cast<void (Derived::*)()>(&Base2::f2);
    
    // 4. 使用using解决歧义
    class Derived2 : public Base1, public Base2 {
    public:
        using Base1::f1;  // 明确使用Base1的f1
        using Base2::f2;  // 明确使用Base2的f2
    };
}

3. 函数对象与lambda表达式

3.1 std::function的通用性

#include <functional>
#include <iostream>

void test_std_function() {
    // std::function可以包装各种可调用对象
    
    // 1. 普通函数
    std::function<int(int, int)> func1 = [](int a, int b) { return a + b; };
    
    // 2. 函数对象(仿函数)
    struct AddFunctor {
        int operator()(int a, int b) const { return a + b; }
    };
    std::function<int(int, int)> func2 = AddFunctor();
    
    // 3. 成员函数指针
    class Math {
    public:
        int multiply(int a, int b) { return a * b; }
        static int divide(int a, int b) { return a / b; }
    };
    
    Math math;
    // 使用std::bind绑定对象和成员函数
    std::function<int(int, int)> func3 = 
        std::bind(&Math::multiply, &math, std::placeholders::_1, std::placeholders::_2);
    
    // 4. 静态成员函数(与普通函数相同)
    std::function<int(int, int)> func4 = &Math::divide;
    
    // 5. lambda表达式
    std::function<int(int, int)> func5 = [](int a, int b) { return a - b; };
    
    // 调用
    std::cout << func1(3, 4) << std::endl;  // 7
    std::cout << func2(3, 4) << std::endl;  // 7
    std::cout << func3(3, 4) << std::endl;  // 12
    std::cout << func4(8, 2) << std::endl;  // 4
    std::cout << func5(7, 3) << std::endl;  // 4
}

3.2 lambda表达式与函数指针

void test_lambda_issues() {
    // 1. 无捕获的lambda可以转换为函数指针
    auto lambda1 = [](int x) { return x * 2; };
    int (*func_ptr1)(int) = lambda1;  // C++11起允许
    
    // 2. 有捕获的lambda不能转换为函数指针
    int multiplier = 3;
    auto lambda2 = [multiplier](int x) { return x * multiplier; };
    // int (*func_ptr2)(int) = lambda2;  // 错误:有捕获
    
    // 3. lambda的独特类型
    auto lambda3 = []() {};
    auto lambda4 = []() {};
    // decltype(lambda3) 和 decltype(lambda4) 是不同的类型
    
    // 4. 通用lambda(C++14)
    auto generic_lambda = [](auto x, auto y) { return x + y; };
    // 可以接受任何支持+操作的类型
    
    // 5. 捕获this指针的问题
    class Widget {
        int value = 42;
    public:
        auto get_lambda() {
            // 捕获this,但要注意生命周期!
            return [this]() { return value; };
        }
        
        // 更好的方法:使用weak_ptr或值捕获
        auto get_safe_lambda() {
            // 值捕获需要的成员
            int local_value = value;
            return [local_value]() { return local_value; };
        }
    };
}

4. 类型擦除与回调设计

4.1 回调接口的设计模式

// 传统C风格回调
typedef void (*Callback)(void* context, int result);
void register_callback(Callback cb, void* context);

// 现代C++类型安全回调
class ICallback {
public:
    virtual ~ICallback() = default;
    virtual void execute(int result) = 0;
};

// 类型擦除包装器
class CallbackWrapper {
    class ICallbackImpl {
    public:
        virtual ~ICallbackImpl() = default;
        virtual void call(int result) = 0;
        virtual std::unique_ptr<ICallbackImpl> clone() const = 0;
    };
    
    template<typename Callable>
    class CallbackImpl : public ICallbackImpl {
        Callable func;
    public:
        explicit CallbackImpl(Callable f) : func(std::move(f)) {}
        void call(int result) override { func(result); }
        std::unique_ptr<ICallbackImpl> clone() const override {
            return std::make_unique<CallbackImpl>(*this);
        }
    };
    
    std::unique_ptr<ICallbackImpl> impl;
    
public:
    template<typename Callable>
    CallbackWrapper(Callable f) : impl(std::make_unique<CallbackImpl<Callable>>(std::move(f))) {}
    
    CallbackWrapper(const CallbackWrapper& other) : impl(other.impl->clone()) {}
    CallbackWrapper& operator=(const CallbackWrapper& other) {
        if (this != &other) {
            impl = other.impl->clone();
        }
        return *this;
    }
    
    void operator()(int result) const { impl->call(result); }
};

void test_callback() {
    // 使用各种可调用对象
    CallbackWrapper c1([](int r) { std::cout << "Lambda: " << r << std::endl; });
    CallbackWrapper c2(std::function<void(int)>([](int r) { std::cout << "Function: " << r << std::endl; }));
    
    struct Functor {
        void operator()(int r) const { std::cout << "Functor: " << r << std::endl; }
    };
    CallbackWrapper c3(Functor());
    
    c1(42);
    c2(100);
    c3(200);
}

4.2 信号-槽机制实现

#include <vector>
#include <functional>
#include <memory>

class Signal {
    std::vector<std::function<void(int)>> slots;
    
public:
    // 连接槽函数
    template<typename Callable>
    void connect(Callable&& slot) {
        slots.emplace_back(std::forward<Callable>(slot));
    }
    
    // 发射信号
    void emit(int value) {
        for (const auto& slot : slots) {
            slot(value);
        }
    }
    
    // 断开连接(需要更复杂的实现来跟踪连接)
};

class Receiver {
public:
    void on_event(int value) {
        std::cout << "Receiver got: " << value << std::endl;
    }
    
    static void static_handler(int value) {
        std::cout << "Static handler: " << value << std::endl;
    }
};

void test_signal_slot() {
    Signal signal;
    Receiver receiver;
    
    // 连接各种类型的槽
    signal.connect([](int v) { std::cout << "Lambda: " << v << std::endl; });
    signal.connect(&Receiver::static_handler);
    
    // 连接成员函数需要绑定对象
    signal.connect(std::bind(&Receiver::on_event, &receiver, std::placeholders::_1));
    
    // 使用lambda捕获对象
    signal.connect([&receiver](int v) { receiver.on_event(v); });
    
    // 发射信号
    signal.emit(42);
    // 输出:
    // Lambda: 42
    // Static handler: 42
    // Receiver got: 42
    // Receiver got: 42
}

5. 性能与优化

5.1 函数指针调用的开销

// 测试各种调用方式的性能
#include <chrono>
#include <functional>

int add(int a, int b) { return a + b; }

struct AddFunctor {
    int operator()(int a, int b) const { return a + b; }
};

void test_performance() {
    constexpr int iterations = 100000000;
    
    // 1. 直接函数调用
    auto start1 = std::chrono::high_resolution_clock::now();
    int sum1 = 0;
    for (int i = 0; i < iterations; ++i) {
        sum1 += add(i, i + 1);
    }
    auto end1 = std::chrono::high_resolution_clock::now();
    
    // 2. 函数指针调用
    int (*func_ptr)(int, int) = add;
    auto start2 = std::chrono::high_resolution_clock::now();
    int sum2 = 0;
    for (int i = 0; i < iterations; ++i) {
        sum2 += func_ptr(i, i + 1);
    }
    auto end2 = std::chrono::high_resolution_clock::now();
    
    // 3. std::function调用
    std::function<int(int, int)> std_func = add;
    auto start3 = std::chrono::high_resolution_clock::now();
    int sum3 = 0;
    for (int i = 0; i < iterations; ++i) {
        sum3 += std_func(i, i + 1);
    }
    auto end3 = std::chrono::high_resolution_clock::now();
    
    // 4. 函数对象调用
    AddFunctor functor;
    auto start4 = std::chrono::high_resolution_clock::now();
    int sum4 = 0;
    for (int i = 0; i < iterations; ++i) {
        sum4 += functor(i, i + 1);
    }
    auto end4 = std::chrono::high_resolution_clock::now();
    
    // 输出时间比较
    // 通常:直接调用 ≈ 函数指针 < 函数对象 < std::function
    // std::function有类型擦除开销
}

5.2 内联与优化障碍

// 函数指针可能阻止内联优化
inline int inline_add(int a, int b) { return a + b; }

void test_inline_issues() {
    // 直接调用可能被内联
    int result1 = inline_add(3, 4);
    
    // 通过函数指针调用通常不会被内联
    int (*ptr)(int, int) = inline_add;
    int result2 = ptr(3, 4);
    
    // 解决方法:使用模板
    template<typename Func>
    int call_and_maybe_inline(Func f, int a, int b) {
        // 如果Func是函数指针或函数对象,编译器可能内联
        return f(a, b);
    }
    
    // 或者使用constexpr函数指针(C++17)
    constexpr int (*constexpr_ptr)(int, int) = inline_add;
    // 在编译时已知的函数指针,编译器可能优化
}

6. 现代C++解决方案

6.1 使用auto和decltype简化类型

// 使用auto简化函数指针声明
auto func_ptr = &add;  // 自动推导为 int(*)(int, int)

// 使用decltype获取函数类型
decltype(add)* another_ptr = add;  // 更清晰的意图

// 模板中自动推导
template<typename Func, typename... Args>
auto call_function(Func f, Args&&... args) -> decltype(f(std::forward<Args>(args)...)) {
    return f(std::forward<Args>(args)...);
}

// 使用类型别名模板
template<typename Signature>
using FunctionPtr = Signature*;

FunctionPtr<int(int, int)> ptr = add;

6.2 使用invoke(C++17)

#include <functional>

void test_invoke() {
    // std::invoke统一了各种可调用对象的调用方式
    
    // 1. 普通函数
    std::invoke(add, 3, 4);
    
    // 2. 成员函数指针
    class MyClass {
    public:
        int value;
        int get_value() const { return value; }
    };
    
    MyClass obj{42};
    int (MyClass::*mem_ptr)() const = &MyClass::get_value;
    std::invoke(mem_ptr, obj);  // 调用 obj.get_value()
    
    // 3. 成员变量指针
    int MyClass::*val_ptr = &MyClass::value;
    std::invoke(val_ptr, obj) = 100;  // obj.value = 100
    
    // 4. 函数对象
    struct Functor {
        int operator()(int x) const { return x * 2; }
    };
    std::invoke(Functor{}, 21);  // 42
    
    // 5. lambda表达式
    auto lambda = [](int x) { return x + 1; };
    std::invoke(lambda, 41);  // 42
}

6.3 完美转发与通用引用

// 通用回调包装器
template<typename Callable, typename... Args>
auto perfect_forward(Callable&& func, Args&&... args)
    -> decltype(std::forward<Callable>(func)(std::forward<Args>(args)...)) {
    return std::forward<Callable>(func)(std::forward<Args>(args)...);
}

// 用于成员函数的包装器
template<typename MemberPtr, typename Class, typename... Args>
auto invoke_member(MemberPtr mem_ptr, Class&& obj, Args&&... args)
    -> decltype((std::forward<Class>(obj).*mem_ptr)(std::forward<Args>(args)...)) {
    return (std::forward<Class>(obj).*mem_ptr)(std::forward<Args>(args)...);
}

7. 实用模式与惯用法

7.1 命令模式实现

#include <memory>
#include <vector>

// 命令接口
class Command {
public:
    virtual ~Command() = default;
    virtual void execute() = 0;
    virtual std::unique_ptr<Command> clone() const = 0;
};

// 函数命令包装器
template<typename Func>
class FunctionCommand : public Command {
    Func func;
    
public:
    explicit FunctionCommand(Func f) : func(std::move(f)) {}
    
    void execute() override {
        func();
    }
    
    std::unique_ptr<Command> clone() const override {
        return std::make_unique<FunctionCommand>(*this);
    }
};

// 命令工厂函数
template<typename Func>
std::unique_ptr<Command> make_command(Func f) {
    return std::make_unique<FunctionCommand<Func>>(std::move(f));
}

// 使用示例
void test_command_pattern() {
    std::vector<std::unique_ptr<Command>> commands;
    
    // 添加各种命令
    commands.push_back(make_command([]() { std::cout << "Command 1" << std::endl; }));
    commands.push_back(make_command([]() { std::cout << "Command 2" << std::endl; }));
    
    class Receiver {
    public:
        void action() { std::cout << "Receiver action" << std::endl; }
    };
    
    Receiver receiver;
    commands.push_back(make_command([&receiver]() { receiver.action(); }));
    
    // 执行所有命令
    for (const auto& cmd : commands) {
        cmd->execute();
    }
}

7.2 策略模式实现

// 使用函数指针的策略模式
class Context {
    using Strategy = int(*)(int, int);
    Strategy strategy;
    
public:
    explicit Context(Strategy s = nullptr) : strategy(s) {}
    
    void set_strategy(Strategy s) { strategy = s; }
    
    int execute_strategy(int a, int b) {
        if (strategy) {
            return strategy(a, b);
        }
        throw std::runtime_error("No strategy set");
    }
};

// 使用std::function的策略模式(更灵活)
class FlexibleContext {
    std::function<int(int, int)> strategy;
    
public:
    template<typename Func>
    explicit FlexibleContext(Func&& f) : strategy(std::forward<Func>(f)) {}
    
    template<typename Func>
    void set_strategy(Func&& f) {
        strategy = std::forward<Func>(f);
    }
    
    int execute_strategy(int a, int b) {
        if (strategy) {
            return strategy(a, b);
        }
        throw std::runtime_error("No strategy set");
    }
};

void test_strategy_pattern() {
    // 使用函数指针
    Context ctx1(add);
    std::cout << ctx1.execute_strategy(3, 4) << std::endl;  // 7
    
    // 使用lambda
    FlexibleContext ctx2([](int a, int b) { return a * b; });
    std::cout << ctx2.execute_strategy(3, 4) << std::endl;  // 12
    
    // 使用函数对象
    struct PowerStrategy {
        int operator()(int a, int b) const { 
            int result = 1;
            for (int i = 0; i < b; ++i) result *= a;
            return result;
        }
    };
    
    ctx2.set_strategy(PowerStrategy());
    std::cout << ctx2.execute_strategy(2, 3) << std::endl;  // 8
}

8. 最佳实践总结

8.1 函数指针与成员函数指针使用指南

// 1. 优先使用lambda和std::function
class ModernCallback {
    std::function<void(int)> callback;
    
public:
    template<typename Func>
    void set_callback(Func&& f) {
        callback = std::forward<Func>(f);
    }
    
    void notify(int value) {
        if (callback) callback(value);
    }
};

// 2. 需要高性能时考虑函数指针
class FastCallback {
    using Callback = void(*)(int);
    Callback callback = nullptr;
    
public:
    void set_callback(Callback cb) { callback = cb; }
    
    void notify(int value) {
        if (callback) callback(value);
    }
};

// 3. 成员函数指针的使用场景
class EventHandler {
    using Handler = void (EventHandler::*)(int);
    Handler handler = nullptr;
    
public:
    void set_handler(Handler h) { handler = h; }
    
    void handle_event(int event) {
        if (handler) (this->*handler)(event);
    }
    
private:
    void default_handler(int) { /* ... */ }
    void special_handler(int) { /* ... */ }
};

// 4. 使用类型别名提高可读性
namespace CallbackTypes {
    using VoidCallback = std::function<void()>;
    using IntCallback = std::function<void(int)>;
    using MemberCallback = std::function<void(int, const std::string&)>;
    
    template<typename T>
    using Ptr = T*;
    
    template<typename Ret, typename... Args>
    using FunctionPtr = Ret(*)(Args...);
}

// 5. 安全地使用成员函数指针
template<typename Class, typename Ret, typename... Args>
class SafeMemberCallback {
    Class* obj = nullptr;
    Ret (Class::*method)(Args...) = nullptr;
    
public:
    SafeMemberCallback() = default;
    
    SafeMemberCallback(Class* o, Ret (Class::*m)(Args...)) 
        : obj(o), method(m) {}
    
    bool is_valid() const { return obj && method; }
    
    Ret operator()(Args... args) {
        if (!is_valid()) {
            throw std::runtime_error("Invalid callback");
        }
        return (obj->*method)(std::forward<Args>(args)...);
    }
};

// 使用示例
class Button {
    SafeMemberCallback<Button, void, int> click_handler;
    
public:
    void set_click_handler(decltype(click_handler) handler) {
        click_handler = handler;
    }
    
    void click() {
        if (click_handler.is_valid()) {
            click_handler(42);  // 传递点击数据
        }
    }
};

8.2 决策流程图

需要回调或策略吗?
│
├── 回调需要捕获局部变量吗?
│   ├── 是 → 使用lambda或std::function + std::bind
│   └── 否 → 
│       ├── 需要最高性能吗?
│       │   ├── 是 → 使用函数指针
│       │   └── 否 → 使用std::function(更灵活)
│
├── 需要调用成员函数吗?
│   ├── 是 → 
│   │   ├── 对象生命周期确定且安全?
│   │   │   ├── 是 → 使用std::bind或lambda捕获this
│   │   │   └── 否 → 使用weak_ptr或值捕获关键数据
│   │   └── 需要存储多个不同类型的回调?
│   │       └── 使用类型擦除(如std::function)
│   └── 否 → 使用普通函数指针或lambda
│
├── 需要在编译时确定调用目标吗?
│   ├── 是 → 使用函数指针或模板参数
│   └── 否 → 使用运行时多态(虚函数或std::function)
│
├── 需要支持多种调用签名吗?
│   ├── 是 → 使用模板或std::function
│   └── 否 → 使用特定签名的函数指针
│
└── 需要序列化或持久化回调吗?
    ├── 是 → 使用函数指针(地址稳定)或注册表模式
    └── 否 → 任意选择

8.3 常见陷阱检查表

// 检查表:使用函数指针和成员函数指针时
class CallbackSafetyCheck {
public:
    void check_before_use() {
        // 1. 检查空指针
        if (callback == nullptr) {
            throw std::runtime_error("Callback is null");
        }
        
        // 2. 检查对象生命周期(针对成员函数)
        if (object_ptr.expired()) {  // 如果使用weak_ptr
            throw std::runtime_error("Object no longer exists");
        }
        
        // 3. 检查线程安全
        // std::lock_guard<std::mutex> lock(mutex);
        
        // 4. 检查异常安全
        try {
            // 调用回调
        } catch (...) {
            // 处理异常,避免传播
        }
        
        // 5. 验证返回值(如果重要)
        auto result = callback();
        if (!validate_result(result)) {
            // 处理无效结果
        }
    }
    
private:
    std::function<int()> callback;
    std::weak_ptr<SomeObject> object_ptr;
    std::mutex mutex;
    
    bool validate_result(int) { /* ... */ return true; }
};

通过理解函数指针和成员函数指针的复杂性和陷阱,并采用现代C++的最佳实践,可以构建更安全、更灵活、更高效的代码。记住,在大多数情况下,std::function和lambda表达式提供了更好的类型安全性和灵活性,而只有在性能极其关键的场景中才需要直接使用原始函数指针。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值