状态模式(C++)
定义
允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。
应用场景
- 在软件构建过程中,某些对象的状态如果改变,其行为也会随之,而发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。
- 如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转化之间引入紧耦合?
结构

代码示例
//State.h
/****************************************************/
#ifndef STATE_H
#define STATE_H
#include <iostream>
using namespace std;
class Lamp;// 抽象状态类
class State
{
public:// 析构函数virtual ~State() {}// 操作函数virtual void handle(Lamp& context) = 0;};// 具体状态类-开
class StateOn : public State
{
public:// 操作函数virtual void handle(Lamp& context);};// 具体状态类-关
class StateOff : public State
{
public:// 操作函数virtual void handle(Lamp& context);};// 灯
class Lamp
{
public:// 构造函数,默认状态关闭Lamp() : m_state(new StateOff()){}// 析构函数~Lamp();// 设置状态void setState(State* state);// 请求void request();private:State* m_state;
};// 操作函数
void StateOn::handle(Lamp& context) {cout << "当前状态:打开" << endl;cout << "执行操作:关闭" << endl;context.setState(new StateOff());
}// 操作函数
void StateOff::handle(Lamp& context) {cout << "当前状态:关闭" << endl;cout << "执行操作:打开" << endl;context.setState(new StateOn());
}// 析构函数
Lamp::~Lamp() {if (m_state) {delete m_state;m_state = nullptr;}
}// 设置状态
void Lamp::setState(State* state) {if (m_state) {delete m_state;m_state = nullptr;}m_state = state;
}// 请求
void Lamp::request() {m_state->handle(*this);
}#endif
//test.cpp
/****************************************************/
#include "State.h"int main()
{Lamp lamp;lamp.request(); // 操作灯lamp.request(); // 操作灯return 0;
}
运行结果

要点总结
- State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象;但同时维持State的接口,这样实现了具体操作与状态转换之间的解耦。
- 为不同的状态引入不同的对象使得状态转换变得更加明确,而且可以保证不会出现状态不一致的情况,因为转换是原子性的——即要么彻底转换过来,要么不转换。
- 如果State对象没有实例变量,那么各个上下文可以共享同一个State对象,从而节省对象开销。
相关文章:
状态模式(C++)
定义 允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。 应用场景 在软件构建过程中,某些对象的状态如果改变,其行为也会随之,而发生变化,比如文档处于只读状态,其支持的行为和读写…...
承泰科技Q3再获30多个智驾项目,新增订单0.86亿!累计近11亿!
中国毫米波雷达市场正处于高速发展期,以承泰科技为代表的本土供应商在前装量产赛道上展示出加速度。 高工智能汽车研究院预测,随着L2及L2持续处于市场增长的高速期,对应毫米波雷达上车量将在2023年实现30-50%的同比增速。 根据高工智能汽车…...
以太网Ethernet通信协议
一、以太网简介 计算机网络可分为局域网(LAN)、 城域网(MAN)、广域网(WAN)、互联网(Initernet)。局域网按传输介质所使用的访问控制方法可分为:以太网(Ethernet)、光纤分布式数据接口(FDDI)、异步传输模式(ATM)、令牌环网(Token Ring)、交换网(Switching) 等&#x…...
内网横向移动—资源约束委派
内网横向移动—资源约束委派 1. 资源约束委派1.1. 基于资源的约束委派的优势1.2. 约束性委派和基于资源的约束性委派配置的差别1.3. 利用条件1.3.1. 什么用户能够修改msDS-AllowedToActOnBehalfOfOtherIdentity属性1.3.2. 将机器加入域的域用户 2. 案例操作2.1. 获取目标信息2.…...
Spring Boot Logback日志格式改为JSON
在阿里云、或者日志分析时使用JSON格式输出日志更加方便。 依赖 增加Logbak JSON解析依赖。 另外需要注意的是JSON格式输出依赖Jackson,根据工程情况按需添加Jackson依赖。 <!--日志--><dependency><groupId>ch.qos.logback.contrib</grou…...
Linux 块设备操作函数
和字符设备的fil_operations一样,块设备也有操作集,为结构体block_device_operations,此结构体定义在include/linux/blkdev.h中,结构体内容如下: struct block_device_operations {int (*open) (struct block_device …...
linux c++网络编程基础:服务端与客户端的实现
在Linux环境下,我们可以使用socket编程来实现网络通信。下面是一个简单的C++版本的客户端和服务端的示例代码。 服务端代码: #include <sys/socket.h> #include <netinet/in.h> #include <unistd.h> #include <string.h> #...
坐标转换-使用geotools读取和转换地理空间表的坐标系(sqlserver、postgresql)
前言: 业务上通过GIS软件将空间数据导入到数据库时,因为不同的数据来源和软件设置,可能导入到数据库的空间表坐标系是各种各样的。 如果要把数据库空间表发布到geoserver并且统一坐标系,只是在geoserver单纯的设置坐标系只是改了…...
JavaScript的主要应用场景有哪些?请描述一下JavaScript的基本数据类型和引用数据类型分别是哪些?
1、JavaScript的主要应用场景有哪些? JavaScript是一种广泛使用的编程语言,它主要用于Web开发、移动应用开发、游戏开发、物联网设备开发等场景。以下是JavaScript的主要应用场景: Web开发:JavaScript是Web开发中最常用的编程语…...
webpack性能优化
文章目录 1. 性能优化-分包2. 动态导入3. 自定义分包4. Prefetch和Preload5. CDN加载配置6. CSS的提取7. terser压缩7.1 Terser在webpack中配置7.2 css压缩 8. Tree Shaking 消除未使用的代码8.1 usedExports 配置8.2 sideEffects配置8.3 CSS实现Tree Shaking 9. Scope Hoistin…...
保存和读取带有透明通道的视频
保存带有透明通道的视频: import osimport imageio from rembg import remove as removBg,new_session from PIL import Image import numpy as np import cv2 from tqdm import tqdmclass cls_rembg():def __init__(self,model_pth):self.session new_session(mo…...
bilibili的评论ip属地显示未知
现象 出于某些原因,我们在日常使用中的大部分平台都开启了IP地址显示,一般会显示当事人所在的地址,这其中就有一些奇怪的地址,(在此不谈魔法)就比如我最近在刷B站的时候,就在评论区发现了一些显…...
[BabysqliV3.0]phar反序列化
文章目录 [BabysqliV3.0]phar反序列化 [BabysqliV3.0]phar反序列化 开始以为是sql注入 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ST1jvadM-1691302941344)(https://raw.githubusercontent.com/leekosss/photoBed/master/202308032140269.png)…...
数据库架构演变过程
🚀 ShardingSphere 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜&…...
webpack 静态模块打包工具
webpack 为什么? 把静态模块内容,压缩,整合,转译等(前端工程化) 把less/sass转成css代码把ES6 降级成ES5支持多种模块文件类型,多种模块标准语法 vite 为什么不直接学习vite 而学习webpack 因为很多项目还是基于webpack来进…...
万界星空科技/免费开源MES系统/免费仓库管理
仓库管理(仓储管理),指对仓库及仓库内部的物资进行收发、结存等有效控制和管理,确保仓储货物的完好无损,保证生产经营活动的正常进行,在此基础上对货物进行分类记录,通过报表分析展示仓库状态、…...
【暑期每日一练】 Epilogue
目录 选择题(1)解析: (2)解析: (3)解析: (4)解析: (5)解析: 编程题题一描述输入描述:输…...
Go微服务实践 - Rpc核心概念理解
概述 从0研究一下Golang已经Golang的微服务生态体系,Golang的微服务首先要从Rpc开始,在升级到Grpc,详细介绍这些技术点都在解决什么技术问题。 Rpc Rpc (Remote Procedure Call) 远程过程调用,简单的理解是一个节点请求另一个节…...
Effective Java笔记(27)消除非受检的警告
用泛型编程时会遇到讲多编译器警告 : 非受检转换警告( unchecked cast warning )、非受检方法调用警告、非受检参数化可变参数类型警告( unchecked parameterized vararg type warning),以及非受检转换警告…...
Dapper
介绍 Dapper是一个轻量级的ORM(对象关系映射)框架,它可以方便地将数据库查询结果映射到.NET对象上,同时也支持执行原生SQL查询。下面我将详细介绍Dapper的使用方法。 安装Dapper 首先,你需要通过NuGet包管理器将Dap…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
Redis相关知识总结(缓存雪崩,缓存穿透,缓存击穿,Redis实现分布式锁,如何保持数据库和缓存一致)
文章目录 1.什么是Redis?2.为什么要使用redis作为mysql的缓存?3.什么是缓存雪崩、缓存穿透、缓存击穿?3.1缓存雪崩3.1.1 大量缓存同时过期3.1.2 Redis宕机 3.2 缓存击穿3.3 缓存穿透3.4 总结 4. 数据库和缓存如何保持一致性5. Redis实现分布式…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
c++第七天 继承与派生2
这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分:派生类构造函数与析构函数 当创建一个派生类对象时,基类成员是如何初始化的? 1.当派生类对象创建的时候,基类成员的初始化顺序 …...
go 里面的指针
指针 在 Go 中,指针(pointer)是一个变量的内存地址,就像 C 语言那样: a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10,通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...
