c++如何让一个对象在其内部状态改变时改变其行为

来源:网站建设作者:河北彩花头衔:网络博主
导读:本期聚焦于小伙伴创作的《c++如何让一个对象在其内部状态改变时改变其行为》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《c++如何让一个对象在其内部状态改变时改变其行为》有用,将其分享出去将是对创作者最好的鼓励。

在c++开发中,当对象的行为依赖于其内部状态,并且状态会在运行时发生变化时,如果直接使用大量的if-else或者switch-case语句判断状态再执行对应逻辑,会导致代码臃肿、扩展性差。状态模式通过将每个状态的行为封装到独立的类中,让对象在状态改变时切换对应的状态类,从而自然改变自身行为,是解决这类问题的优选方案。

c++如何让一个对象在其内部状态改变时改变其行为

状态模式的核心结构

状态模式主要包含以下几个角色:

  • 环境类(Context):维护当前状态对象的实例,对外提供操作接口,状态变化时会切换持有的状态对象。
  • 抽象状态类(State):定义所有状态共同的行为接口,所有具体状态类都需要实现这个接口。
  • 具体状态类(ConcreteState):实现抽象状态类的接口,每个类对应一种具体状态,实现该状态下的具体行为逻辑。

c++实现状态模式示例

我们以一个简单的电梯运行为例,电梯有停止、运行、故障三种状态,不同状态下对开门、关门、运行指令的响应不同,下面用状态模式实现这个场景。

1. 定义抽象状态类

首先定义电梯状态的抽象接口,包含开门、关门、运行三个操作:

// 前置声明环境类
class Elevator;

// 抽象状态类
class ElevatorState {
public:
    virtual ~ElevatorState() = default;
    // 开门操作
    virtual void openDoor(Elevator* elevator) = 0;
    // 关门操作
    virtual void closeDoor(Elevator* elevator) = 0;
    // 运行操作
    virtual void run(Elevator* elevator) = 0;
};

2. 实现具体状态类

分别实现停止、运行、故障三个具体状态类:

#include <iostream>
#include <string>

// 停止状态
class StopState : public ElevatorState {
public:
    void openDoor(Elevator* elevator) override;
    void closeDoor(Elevator* elevator) override;
    void run(Elevator* elevator) override;
};

// 运行状态
class RunState : public ElevatorState {
public:
    void openDoor(Elevator* elevator) override;
    void closeDoor(Elevator* elevator) override;
    void run(Elevator* elevator) override;
};

// 故障状态
class FaultState : public ElevatorState {
public:
    void openDoor(Elevator* elevator) override;
    void closeDoor(Elevator* elevator) override;
    void run(Elevator* elevator) override;
};

// 停止状态的行为实现
void StopState::openDoor(Elevator* elevator) {
    std::cout << "电梯已停止,开门成功" << std::endl;
}

void StopState::closeDoor(Elevator* elevator) {
    std::cout << "电梯已停止,关门成功" << std::endl;
}

void StopState::run(Elevator* elevator) {
    std::cout << "电梯停止状态,开始运行" << std::endl;
    // 切换到运行状态
    // 实际实现中会在Elevator类中提供设置状态的方法
}

// 运行状态的行为实现
void RunState::openDoor(Elevator* elevator) {
    std::cout << "电梯正在运行,禁止开门" << std::endl;
}

void RunState::closeDoor(Elevator* elevator) {
    std::cout << "电梯正在运行,门已关闭" << std::endl;
}

void RunState::run(Elevator* elevator) {
    std::cout << "电梯已经在运行中" << std::endl;
}

// 故障状态的行为实现
void FaultState::openDoor(Elevator* elevator) {
    std::cout << "电梯故障,无法开门" << std::endl;
}

void FaultState::closeDoor(Elevator* elevator) {
    std::cout << "电梯故障,无法关门" << std::endl;
}

void FaultState::run(Elevator* elevator) {
    std::cout << "电梯故障,无法运行" << std::endl;
}

3. 实现环境类

环境类维护当前状态,提供操作接口并委托给当前状态对象执行:

class Elevator {
private:
    ElevatorState* currentState;
    // 具体状态实例,实际开发中可以用智能指针管理生命周期
    StopState* stopState;
    RunState* runState;
    FaultState* faultState;

public:
    Elevator() {
        stopState = new StopState();
        runState = new RunState();
        faultState = new FaultState();
        // 初始状态为停止状态
        currentState = stopState;
    }

    ~Elevator() {
        delete stopState;
        delete runState;
        delete faultState;
    }

    // 设置当前状态
    void setState(ElevatorState* state) {
        currentState = state;
    }

    // 获取停止状态实例
    ElevatorState* getStopState() {
        return stopState;
    }

    // 获取运行状态实例
    ElevatorState* getRunState() {
        return runState;
    }

    // 获取故障状态实例
    ElevatorState* getFaultState() {
        return faultState;
    }

    // 开门操作
    void openDoor() {
        currentState->openDoor(this);
    }

    // 关门操作
    void closeDoor() {
        currentState->closeDoor(this);
    }

    // 运行操作
    void run() {
        currentState->run(this);
    }
};

4. 完善状态切换逻辑

补充之前具体状态类中状态切换的实现,让状态可以正确流转:

// 补充StopState的run方法实现
void StopState::run(Elevator* elevator) {
    std::cout << "电梯停止状态,开始运行" << std::endl;
    elevator->setState(elevator->getRunState());
}

// 补充RunState的状态切换示例,比如故障后切换状态
// 可以在RunState中增加故障触发的方法,这里简化为运行状态下触发故障
void RunState::openDoor(Elevator* elevator) {
    std::cout << "电梯正在运行,禁止开门,触发故障保护" << std::endl;
    elevator->setState(elevator->getFaultState());
}

5. 测试代码

编写测试代码验证状态模式的效果:

int main() {
    Elevator elevator;
    
    std::cout << "=== 初始停止状态操作 ===" << std::endl;
    elevator.openDoor();
    elevator.closeDoor();
    elevator.run();

    std::cout << "n=== 运行状态操作 ===" << std::endl;
    elevator.openDoor(); // 运行状态下开门触发故障
    elevator.run();

    std::cout << "n=== 故障状态操作 ===" << std::endl;
    elevator.openDoor();
    elevator.closeDoor();

    return 0;
}

状态模式的优势与适用场景

状态模式的优势非常明显:首先它消除了大量的条件判断语句,让代码逻辑更清晰;其次新增状态时只需要新增具体状态类,不需要修改原有代码,符合开闭原则;另外每个状态的行为独立封装,职责单一,便于维护和测试。

它适合以下场景:对象的行为依赖其状态,并且状态会在运行时频繁变化;代码中包含大量与对象状态相关的条件判断语句,导致代码难以维护和扩展。比如游戏角色的状态切换、订单流程的状态流转、设备的工作状态管理等场景都可以使用状态模式实现。

注意事项

使用状态模式时也需要注意,如果对象的状态很少,且状态变化逻辑简单,使用状态模式会增加类的数量,反而让代码变复杂。另外状态对象的生命周期管理需要注意,避免内存泄漏,实际开发中可以使用std::unique_ptr等智能指针管理状态对象的生命周期。

状态模式C++设计模式对象行为修改时间:2026-07-14 09:42:38

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。