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

C++如何将类虚函数存入std::vector等容器并解决相关编译报错

问题原因

你遇到的编译报错是因为非静态成员函数的调用依赖类实例对象,直接取成员函数的地址得到的是成员函数指针,隐含了this参数,和你声明的std::function<int(int)>签名不匹配,C++标准不允许这种隐式转换。

解决方案

你可以通过lambda捕获当前实例的this指针,把虚函数调用包装成符合签名的可调用对象存入vector即可,这种方式会自动触发虚函数的多态调度,完全符合你的业务需求。

另外你给出的A类代码存在笔误,声明了两个fun1,第二个应为fun2,同时建议给虚函数加override关键字、给基类加虚析构函数避免内存泄漏。

修正后的完整代码如下:

#include <vector>
#include <functional>

class Base
{
public:
    virtual int fun1(int inp) = 0;
    virtual int fun2(int inp) = 0;
    int init(int inp, std::vector<std::function<int(int)>> Callbacks, int index)
    {
        return index == 0 ? Callbacks[0](inp) : Callbacks[1](inp);
    }
    int run()
    {
        // lambda捕获当前实例this,包装虚函数调用
        return init(5, {
            [this](int v) { return fun1(v); },
            [this](int v) { return fun2(v); }
        }, 0);
    }
    // 基类添加虚析构函数避免内存泄漏
    virtual ~Base() = default;
};

class A : public Base
{
    int fun1(int inp) override
    {
        return inp * 10;
    }
    int fun2(int inp) override // 修正原代码笔误,原代码重复声明了fun1
    {
        return inp * 100;
    }
};

class B : public Base
{
    int fun1(int inp) override
    {
        return inp * 20;
    }
    int fun2(int inp) override
    {
        return inp * 200;
    }
};

int main(int argc, char const* argv[])
{
    auto f = new B;
    int e = f->run(); // 运行结果为100,符合预期
    delete f;
    return 0;
}

疑问解答

  • 能不能将虚函数绑定到容器中? 完全可以,只要把类实例和成员函数绑定后适配std::function的签名即可,调用时会自动触发多态,走派生类的实现逻辑。
  • 能不能将lambda函数声明为虚函数? 不行。C++标准明确规定虚函数只能是类的非静态成员函数,lambda本质是匿名函数对象,拥有独立的类型,无法作为基类的虚函数声明。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 18:39:03