妙用 std::optional 类简化状态机设计
source link: https://netcan.github.io/2022/05/16/%E5%A6%99%E7%94%A8-std-optional-%E7%B1%BB%E7%AE%80%E5%8C%96%E7%8A%B6%E6%80%81%E6%9C%BA%E8%AE%BE%E8%AE%A1/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
妙用 std::optional 类简化状态机设计
一些类可能存在和生命周期相关的状态,例如该类中常常包含着 Start
和Stop
等接口,通常而言,对象被构造动作相当于做初始化,而 Start
方法才真正干活,例如创建线程,然后 Stop
方法去停掉线程,那么对于析构函数而言,除了本身需要销毁的那部分动作外,还需要检查 Start
的状态,以便判断是否需要Stop
。
一旦引入 Start
和Stop
等接口,意味着该类的作者需要追踪这个类的状态,并且这个类的每个接口可能都需要判断这个状态,总之,他需要考虑的因素也多了些:
- 如果用户重复
Start
怎么办? - 如果用户仅仅
Stop
怎么办? - 某个接口调用的时候,是否需要保证
Start
状态?如果没有怎么处理? - 析构行为需要考虑
Start
状态
如果将 Start
的语义收编到构造函数,Stop
语义收编到析构函数,那么因为该状态的消除意味着复杂度也降了很多,代码因此也就很简洁。如果用户仍然需要延迟 Start
的语义,那么可以交由类 std::optional
组合而成,例如在需要 Start
的地方使用 emplace
接口构造出该对象,在需要 Stop
的地方使用 reset
接口销毁对象:
class UserObj {
// ...
private:
// 使用 optional 表达额外的 Start/Stop 语义
std::optional<Thread> m_thread;
};
std::optional<Thread>
类由 C++17 标准引入,它相当于组合了状态类与标记字段,并且无需动态分配内存,可以理解大小为 sizeof(Thread) + sizeof(bool)
,这要比使用unique_ptr<Thread>
的方式要高效的多。
- 本文标题:妙用 std::optional 类简化状态机设计
- 本文字数:444
- 本文作者:Netcan
- 发布时间:2022年05月16日 - 14时49分
- 最后更新:2022年05月16日 - 15时16分
- 原始链接:https://netcan.github.io/2022/05/16/妙用-std-optional-类简化状态机设计/
- 版权声明:"署名-非商用-相同方式共享 3.0"转载请保留原文链接及作者。
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK