如何在C++中将拥有同名成员函数的不同类实例作为成员函数参数传入
C++ 实现方案
C++中针对这类「接收具备同名成员函数的不同类实例」的场景,常用两种实现思路:
方案1:面向对象动态多态(经典命令模式,支持运行时动态切换命令类型)
这是最通用的标准实现,通过抽象基类定义统一接口,子类继承实现对应逻辑:
#include <iostream> #include <memory> // 抽象命令基类,定义统一接口 class Command { public: virtual ~Command() = default; virtual int execute(int currValue) const = 0; virtual int undo(int currValue) const = 0; }; class AddCommand : public Command { private: int valueToAdd; public: AddCommand(int val) : valueToAdd(val) {} int execute(int currValue) const override { return currValue + valueToAdd; } int undo(int currValue) const override { return currValue - valueToAdd; } }; class SubtractCommand : public Command { private: int valueToSubtract; public: SubtractCommand(int val) : valueToSubtract(val) {} int execute(int currValue) const override { return currValue - valueToSubtract; } int undo(int currValue) const override { return currValue + valueToSubtract; } }; class Calculator { private: int value; public: Calculator(int initVal) : value(initVal) {} int getValue() const { return value; } // 接收基类的智能指针/引用即可传入所有子类实例 void executeCommand(const std::unique_ptr<Command>& command) { value = command->execute(value); } }; int main() { Calculator calculator(0); calculator.executeCommand(std::make_unique<AddCommand>(5)); std::cout << calculator.getValue() << std::endl; // 输出5 calculator.executeCommand(std::make_unique<SubtractCommand>(5)); std::cout << calculator.getValue() << std::endl; // 输出0 return 0; }
如果不需要管理命令的生命周期,也可以直接传const Command&作为参数,调用时直接传栈上的实例即可。
方案2:模板静态多态(编译期确定类型,无运行时开销,和JS鸭子类型行为一致)
如果你不需要在运行时动态决定传入的命令类型,只需要编译期校验类型是否具备execute方法,可以用模板实现,不需要继承关系:
#include <iostream> class AddCommand { private: int valueToAdd; public: AddCommand(int val) : valueToAdd(val) {} int execute(int currValue) const { return currValue + valueToAdd; } int undo(int currValue) const { return currValue - valueToAdd; } }; class SubtractCommand { private: int valueToSubtract; public: SubtractCommand(int val) : valueToSubtract(val) {} int execute(int currValue) const { return currValue - valueToSubtract; } int undo(int currValue) const { return currValue + valueToSubtract; } }; class Calculator { private: int value; public: Calculator(int initVal) : value(initVal) {} int getValue() const { return value; } // 模板函数,只要传入的command有符合签名的execute方法即可编译通过 template<typename T> void executeCommand(const T& command) { value = command.execute(value); } }; int main() { Calculator calculator(0); calculator.executeCommand(AddCommand(5)); std::cout << calculator.getValue() << std::endl; // 输出5 calculator.executeCommand(SubtractCommand(5)); std::cout << calculator.getValue() << std::endl; // 输出0 return 0; }
这种实现的行为和你给出的JS代码最接近,不需要提前定义接口继承关系,只要类型具备对应方法就可以传入,仅在编译期做校验,没有虚函数的运行时开销。
内容的提问来源于stack exchange,提问作者Shiqi
相关产品推荐
相关产品推荐

