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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 04:51:03