You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++中如何执行子类对象虚成员方法的函数指针数组?

实现带共同基类的虚成员函数指针数组

首先定义基类和派生类,确保虚函数签名一致:

#include <iostream>

// 基类A,定义纯虚函数
class A {
public:
    virtual void func() const = 0;
    virtual ~A() = default; // 虚析构避免内存泄漏
};

// 派生类B,重写虚函数
class B : public A {
public:
    void func() const override {
        std::cout << "B::func() called\n";
    }
};

// 派生类C,重写虚函数
class C : public A {
public:
    void func() const override {
        std::cout << "C::func() called\n";
    }
};

接下来创建成员函数指针数组并调用:

int main() {
    // 定义匹配虚函数签名的成员函数指针类型
    using FuncPtr = void (A::*)() const;

    // 初始化数组,存放B和C的虚成员函数指针
    FuncPtr funcArray[] = { &B::func, &C::func };

    // 创建派生类对象实例
    B b_instance;
    C c_instance;

    // 直接通过对象调用数组中的函数指针
    (b_instance.*funcArray[0])();
    (c_instance.*funcArray[1])();

    // 也可以结合基类指针实现多态调用
    A* a_ptrs[] = { &b_instance, &c_instance };
    for (size_t i = 0; i < sizeof(funcArray)/sizeof(funcArray[0]); ++i) {
        (a_ptrs[i]->*funcArray[i])();
    }

    return 0;
}

关键注意点

  • 成员函数指针的类型必须与虚函数的完整签名匹配(包括const修饰符、参数列表等),否则无法兼容。
  • 调用成员函数指针时必须提供对应类的对象实例,或者通过基类指针/引用调用(此时依然遵循虚函数的多态逻辑)。

无共同基类的实现方案

如果B和C没有共同父类,但拥有签名一致的成员函数,可以用std::function包装器统一调用接口:

#include <iostream>
#include <functional>

class B {
public:
    void func() const {
        std::cout << "B::func() called\n";
    }
};

class C {
public:
    void func() const {
        std::cout << "C::func() called\n";
    }
};

int main() {
    // 方案1:用std::bind绑定对象和成员函数
    std::function<void()> func_array[] = {
        std::bind(&B::func, B()),
        std::bind(&C::func, C())
    };

    // 方案2:用lambda捕获对象实例
    B b_instance;
    C c_instance;
    std::function<void()> func_array2[] = {
        [&b_instance]() { b_instance.func(); },
        [&c_instance]() { c_instance.func(); }
    };

    // 执行数组中的函数
    for (auto& func : func_array) {
        func();
    }

    for (auto& func : func_array2) {
        func();
    }

    return 0;
}

关键注意点

  • 利用std::function可以将不同类的成员函数统一为相同的可调用类型,无需依赖共同基类。
  • lambda捕获对象时要注意生命周期:如果捕获的是局部对象,要确保调用lambda时对象仍有效。

内容的提问来源于stack exchange,提问作者FourierFlux

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 12:25:15