如何仅允许传入函数的Class A构造调用并在构造时执行该函数
实现仅通过传入函数创建Class A对象的方案
先搞懂你问的函数指针语法
int (*const fcnPtr)(); 可以拆成两部分理解:
(*const fcnPtr):fcnPtr是一个不可修改的指针(指针本身不能指向别的函数),它指向一个函数int ():这个被指向的函数,返回值是int,且没有参数
如果你的初始化函数是无返回值的,对应的函数指针类型应该是void (*const fcn)();如果需要函数能操作A对象,更实用的类型是void(*)(A&)(指向接受A引用、无返回值的函数)。
核心实现思路
要达成「必须传入函数才能创建A对象,且构造时执行该函数」的目标,关键做两件事:
- 禁用默认构造函数:确保用户不能直接创建A对象,必须通过带函数参数的构造函数
- 构造函数接受函数指针/可调用对象:在构造体内执行传入的函数,让它完成成员设置或构造计算
方案1:用函数指针实现(轻量、无额外开销)
这是最直接的实现方式,适合不需要复杂可调用对象的场景:
步骤1:定义初始化函数
这个函数要能操作A对象,所以参数设为A的引用:
void initA(A& obj) { // 这里可以做构造计算、设置对象成员 obj.setMember(42); }
步骤2:修改Class A的代码
禁用默认构造,添加带函数指针的构造函数:
class A { private: int m_member = 0; // 禁用默认构造函数,强制必须传入函数 A() = delete; public: // 构造函数接受函数指针,参数为A的引用 explicit A(void(*initFunc)(A&)); // 成员函数:用于设置成员(示例) void setMember(int val) { m_member = val; } // 成员函数:用于验证结果(示例) int getMember() const { return m_member; } }; // 构造函数的实现:执行传入的初始化函数 A::A(void(*initFunc)(A&)) { initFunc(*this); // 把当前正在构造的对象传给初始化函数 }
步骤3:创建A对象(必须传入函数)
int main() { // 正确:传入初始化函数创建对象,构造时会执行initA A myObj(initA); // 错误:编译失败,因为默认构造函数已被禁用 // A invalidObj; // 验证结果:输出42 cout << myObj.getMember() << endl; return 0; }
方案2:用std::function实现(支持更灵活的可调用对象)
如果需要支持lambda表达式、带捕获的lambda、仿函数等,用std::function会更灵活(需要包含<functional>头文件):
#include <functional> class A { private: int m_member = 0; A() = delete; public: // 构造函数接受std::function,参数为A的引用 explicit A(std::function<void(A&)> initFunc) { initFunc(*this); } void setMember(int val) { m_member = val; } int getMember() const { return m_member; } }; // 使用示例:传入lambda表达式 int main() { A myObj([](A& obj) { obj.setMember(100); }); cout << myObj.getMember() << endl; // 输出100 return 0; }
两种方案对比
- 函数指针:性能最优,无额外开销,但只能指向普通函数,不支持带捕获的lambda
- std::function:灵活性更高,支持所有可调用对象,但有轻微的性能开销(一般场景可忽略)
内容的提问来源于stack exchange,提问作者Rosenkohl435834
相关产品推荐
相关产品推荐

