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
相关产品推荐
相关产品推荐

