1. 命令模式基础与C++实现
命令模式是GoF 23种设计模式中最具实用性的行为型模式之一,它将请求封装为独立对象,使不同请求的参数化、队列化和日志化成为可能。在C++中实现经典命令模式通常包含以下核心组件:
- Command:抽象命令接口,声明执行操作的execute()方法
- ConcreteCommand:具体命令实现,绑定接收者与动作
- Invoker:触发命令执行的调用者
- Receiver:知道如何执行请求的实际操作对象
典型实现如下:
cpp复制// 接收者类
class Receiver {
public:
void Action() {
std::cout << "Receiver执行实际操作" << std::endl;
}
};
// 抽象命令接口
class Command {
public:
virtual ~Command() = default;
virtual void Execute() = 0;
};
// 具体命令
class ConcreteCommand : public Command {
public:
ConcreteCommand(Receiver* receiver) : receiver_(receiver) {}
void Execute() override {
receiver_->Action();
}
private:
Receiver* receiver_;
};
// 调用者
class Invoker {
public:
void SetCommand(Command* command) {
command_ = command;
}
void ExecuteCommand() {
if (command_) {
command_->Execute();
}
}
private:
Command* command_ = nullptr;
};
这种基础实现虽然清晰,但在实际C++项目中往往会遇到几个典型问题:
- 命令对象生命周期管理复杂(原始指针易导致内存泄漏)
- 不支持参数化命令构造
- 缺乏撤销/重做等扩展功能
- 多线程环境下命令调度存在竞态条件
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 现代C++命令模式变体实现
2.1 智能指针管理命令生命周期
使用std::unique_ptr可以优雅解决命令对象的所有权问题:
cpp复制class Invoker {
public:
void SetCommand(std::unique_ptr<Command> command) {
command_ = std::move(command);
}
void ExecuteCommand() {
if (command_) {
command_->Execute();
}
}
private:
std::unique_ptr<Command> command_;
};
// 使用示例
auto receiver = std::make_unique<Receiver>();
auto command = std::make_unique<ConcreteCommand>(receiver.get());
Invoker invoker;
invoker.SetCommand(std::move(command));
invoker.ExecuteCommand();
注意:当需要共享命令对象时,应使用std::shared_ptr,但要注意避免循环引用
2.2 模板化命令接口
通过模板技术可以实现类型安全的命令参数传递:
cpp复制template <typename Receiver, typename... Args>
class GenericCommand : public Command {
public:
using ActionType = void (Receiver::*)(Args...);
GenericCommand(Receiver* receiver, ActionType action, Args... args)
: receiver_(receiver), action_(action), args_(std::forward<Args>(args)...) {}
void Execute() override {
std::apply([this](auto&&... args) {
(receiver_->*action_)(std::forward<decltype(arg
