设为首页 加入收藏

TOP

使用C++实现一套简单的状态机模型――原理解析(一)
2015-07-20 17:12:11 来源: 作者: 【 】 浏览:5
Tags:使用 实现 简单 状态 模型 原理 解析
在上一文中,我们介绍了该状态机模型的使用方法。通过例子,我们发现可以使用该模型快速构建满足基本业务需求的状态机。本文我们将解析该模型的基础代码,以便大家可以根据自己状态机特点进行修改。(转载请指明出于breaksoftware的csdn博客)

该模板库的基础方法实现在之后给出的工程的AutoStateChart.h中,该文件一共215行,其中有16行是辅助调试代码。以上一文中状态机类为例:

class CMachine_Download_Run_App :
    public AutoStateChart::CAutoStateChartMachine
  
CMachine_Download_Run_App类继承于模板类CAutoStateChartMachine,该模板类有两个参数:继承类自身和CStoreofMachine。CStoreofMachine类顾名思义,其是状态机中用于存储数据的类。为什么要设计这样的类?因为在我们的状态机模型中,每个基础状态都是割裂的。这样设计的一个好处便是我们可以让每个基础状态的逻辑代码独立,和其他模块没有任何耦合。当我们要删除某个状态时,我们只要将它从状态机的跳转声明中摘除即可。当我们要新增某个状态时,我们也只要在状态机跳转中做相应声明即可。但是往往优点也伴随着缺点:它使得每个基础状态类的数据交互产生了障碍。特别是没有上下文关系的基础状态,跳跃性的传递信息将变得非常困难。于是我们就需要一个存活于整个状态机声明周期的“ 数据库”,它可以被每个基础状态类访问和修改。于是CStoreofMachine就应运而生。因为该类比较独立,所以我们先从该类开始解析。首先我们看下该类的声明:

#pragma once
#include "AutoStateChart.h"

#define PROPERTY(type,name)													\
public:																		\
	void Set##name(const type& n) {										    \
		m_##name = n;														\
	}																		\
	type Get##name() {														\
		return m_##name;													\
	}																		\
	__declspec(property(get = Get##name, put = Set##name)) type Prop##name;	\
private:																	\
	type m_##name;															\


class CStoreofMachine{
	PROPERTY(std::string, ValueString);
	PROPERTY(std::wstring, ValueWString);
    PROPERTY(int, ValueInt);
};
该类的写法可能只适合于 windows的vs平台,其他平台没论证过。其实它的内容是非常简单的,就是暴露成员变量的set和get方法。只是我觉得这种写法比较有意思,才在这儿罗列下。
我们再看下该类在模板中的使用,我们先从最基础的类开始解析

	class CEmpytLocalStore{};

	template
  
   
	class CLocalStoreAccess{
	public:
		typedef boost::function< Store& () > func;
		Store& GetStore(){return m_pFunc();};
		void SetStore(func& pCallback){m_pFunc = pCallback;};
	public:
		func m_pFunc;
	};
  
我们先定义了一个空类――CEmptyLocalStore,它相当于一个默认的“数据库”。当模板的使用者不需要“数据库”时,就可以在模板中不声明“数据库”类,此时我们的CEmptyLocalStore就生效了。比如我们上例的状态机可以改成:

class CMachine_Download_Run_App :
    public AutoStateChart::CAutoStateChartMachine
  
CLocalStoreAccess类主要提供如下作用:

设置访问“数据库”类对象的方法――SetStore 获取“数据库”类对象――GetStore 成员变量m_pFunc是一个函数指针,用于获取“数据库”类对象。该变量将由CLoaclStoreAccess继承类设置,相当于CLocalStoreAccess暴露了设置访问“数据库”类对象的能力。而它并不保存“数据库”类对象――它只提供“访问”能力,而不提供“存储”能力。
	template
  
   
	class CLocalStoreBase:
		public boost::enable_shared_from_this
   
    >, public CLocalStoreAccess
    
      { public: void Init(){ func pfunc = boost::bind(&CLocalStoreBase
     
      ::_GetStore, shared_from_this()); SetStore(pfunc);}; private: Store& _GetStore(){return m_Store;}; private: Store m_Store; };
     
    
   
  
CLoaclStoreBase类的私有成员变量m_Store就是“数据库”类对象,即该类提供了“存储”功能。它继承于CLoaclStoreAccess类,使得该类具备了访问数据库的能力――虽然它的私有方法可以访问“数据库”类对象,但是我还是希望将这些能力分开。因为之后介绍的基础状态类要有“访问”的能力,而不应该具备“存储”的能力。如果不将这些能力进行拆分,将会导致层次结构混乱。
CLoaclStoreBase类的init方法,打通了和ClocalStoreAccess的关系――设置函数指针。
介绍完用于存储上下文的模板类后,我们现在可以关注下状态机相关的类了。我们先看上一文中一个基础状态类的例子
class CSimpleState_Download_From_A :
    public AutoStateChart::CAutoStateChartBase
  
CSimpleState_Download_From_A类继承于CAutoStateChartBase模板类。第一个模板参数是继承类自身,第二个是它所属的状态机,第三个是“数据库”类。我们在看下CAutoStateChartBase类的声明

	template
  
   
	class CAutoStateChartBase:
		public boost::enable_shared_from_this
   
    >, public CLocalStoreAccess
    
      { BOOST_TYPEOF_REGISTER_TYPE(T) public: std::string GetCurrentState(){ return typeid(T).name();}; bool IsComposite
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇hdu 2844 多重背包 下一篇使用C++实现一套简单的状态机模型..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·有没有哪些高效的c++ (2025-12-27 08:20:57)
·Socket 编程时 Accep (2025-12-27 08:20:54)
·计算机网络知识点总 (2025-12-27 08:20:52)
·一篇说人话的文章, (2025-12-27 07:50:09)
·Python Web框架哪家 (2025-12-27 07:50:06)