现在的位置: 首页 > 综合 > 正文

【设计模式】–C++设计模式类库 Loki介绍与用法

2013年12月02日 ⁄ 综合 ⁄ 共 4328字 ⁄ 字号 评论关闭

http://www.usidcbbs.com/simple/?t2428.html

http://book.douban.com/subject/1119904/

C++设计模式类库 Loki介绍与用法

Loki是由Andrei编写的一个与《Modern C++ Design》(C++设计新思维)一书配套发行的C++代码库。
它不仅把C++模板的功能发挥到了极致,而且把类似设计模式这样思想层面的东西通过库来提供。
本篇文章介绍如何利用Loki来轻松地实现一些设计模式。
由于Loki使用了大量牛X到爆的模板技巧,对编译器的要求是很苛刻的,官方兼容列表里只列出了VC7.1以上版本及GCC3.4以上版本。如果你象我一样喜欢用C++Builder6或VC6,可以去下载《Modern C++ Design》配套源码,那里面的Loki提供了对其它不兼容编译器的移植代码,只是版本低了一点,有些接口有些差别。

最后,BTW,《Modern C++ Design》确实是一本好书,在这里也顺便推荐一下^_^

Loki的下载地址是http://sourceforge.net/projects/loki-lib/,目前最新版本是Loki 0.1.7,后面的代码都使用这个版本作为测试标准。

编译

Loki库提供了N多种编译途经,你可以直接打开项目文件(VC、Code::Block、Cpp-Dev等IDE)编译,也可以用传统的makefile来make,还可以直接用批处理文件编译。象我这种被IDE惯坏的人,一般都是直接把src目录里的代码加入到项目中了事。

Singleton模式(单件模式)

Singleton模式确保一个类在系统中只有一个实例。比如一个窗口系统中只能有一个鼠标对象,只有一个屏幕对象,一个剪切板对象...。我们可以用一个全局变量来做这些工作,但它不能防止实例化多个对象。一个更好的办法是让类自身保存它的唯一实例,并且不允许创建其它实例,这就是Singleton模式。

Loki库的SingletonHolder类提供了对Singleton模式的支持

头文件

  1. #include <loki/Singleton.h>

类型定义

  1. template<
  2.     typename T,
  3.     templateclass > class CreationPolicy = CreateUsingNew,
  4.     templateclass > class LifetimePolicy = DefaultLifetime,
  5.     templateclassclass > class ThreadingModel = ::Loki::SingleThreaded,
  6.     class MutexPolicy = ::Loki::Mutex>
  7. class Loki::SingletonHolder;

Loki的类大部分都是基于策略编程的,其中最主要的是CreationPolicy,它决定了怎样生成一个类实例,可选的有:

  • template<template<class> class Alloc> struct CreateUsing; 在分配器分配的内存中生成实例,如
  • template <class T> struct CreateStatic 生成静态实例
  • template <class T> struct CreateUsingMalloc 使用malloc申请内存并在其中生成实例
  • template <class T> struct CreateUsingNew 使用new生成实例(默认)

示例代码

  1. class MyClass{
  2. public:
  3.     // 有默认构造
  4.     MyClass(){;}
  5.     // 显示自己所在的内存地址,用以区分是否是同一个对象
  6.     void ShowPtr()
  7.     {
  8.         std::cout << this << std::endl;
  9.     }
  10. };
  11. // 定义Singleton的MyClass
  12. typedef Loki::SingletonHolder<MyClass> MyClassSingleton;
  13.  
  14. int _tmain(int argc, _TCHAR* argv[])
  15. {
  16.     // 通过Instance()静态方法取得MyClass实例
  17.     MyClass& v = MyClassSingleton::Instance();
  18.     v.ShowPtr();
  19.     // MyClassSingleton::Instance()总是返回同一个MyClass实例
  20.     MyClassSingleton::Instance().ShowPtr();
  21.     return 0;
  22. }

Loki::SingletonHolder默认的CreationPolicy策略要求类必须有默认构造,如MyClass这样。如果需要包装没有默认构造的类的话,我们就得自定义一个CreationPolicy策略,好在CreationPolicy策略比较简单,先看看Loki中默认的CreateUsingNew吧:

  1. template <class T> struct CreateUsingNew
  2. {
  3.     static T* Create()
  4.     { return new T; }
  5.  
  6.     static void Destroy(T* p)
  7.     { delete p; }
  8. };

呵呵,简单吧,只是简单的Create和Destroy而已。

我们只要修改Create()静态方法,new一个自己的对象就可以了,当然随便多少构造参数都可以在这里写上去啦。另外,如有必要,也可以做一些其它初始工作哦。

  1. class MyClass2{
  2. public:
  3.     // 构造里要求两个整数
  4.     MyClass2(int,int){;}
  5.     void ShowPtr()
  6.     {
  7.         std::cout << this << std::endl;
  8.     }
  9. };
  10. // 我们自己的CreationPolicy策略
  11. template<class T>
  12. class CreateMyClass2UsingNew:
  13.     public Loki::CreateUsingNew<T>
  14. {
  15. public:
  16.     static T* Create()
  17.     { return new T(0,0); }
  18. };
  19. // 定义使用CreateMyClass2UsingNew策略的Singleton类
  20. typedef Loki::SingletonHolder<MyClass2,
  21.     CreateMyClass2UsingNew> MyClass2Singleton;
  22. // 使用之
  23. int _tmain(int argc, _TCHAR* argv[])
  24. {
  25.     MyClass2Singleton::Instance().ShowPtr();
  26.     MyClass2Singleton::Instance().ShowPtr();
  27.     return 0;
  28. }



usidc5 2011-01-18 16:48

对象工厂 Object Factory

又名简单工厂模式,貌似不属于设计模式范畴。它的作用是把对象的创建工作集中起来,并使创建工作与其它部分解耦。比如下面这个函数也可当作简单工厂:

  1. CWinBase* Create(string s)
  2. {
  3.     if(s == "Edit")
  4.         return new CEdit;
  5.     else if(s == "Button")
  6.         return new CButton;
  7.     ...
  8. }

Loki库的Factory类提供了对简单工厂模式的支持。

头文件

  1. #include 

类型

  1. template<
  2.     class AbstractProduct, // “产品”基类型
  3.     typename IdentifierType, // 用什么区分各产品
  4.     typename CreatorParmTList = NullType, // 生成器参数
  5.     templatetypenameclass > class FactoryErrorPolicy = DefaultFactoryError>
  6. class Loki::Factory;

成员方法

bool Register(const IdentifierType& id, ProductCreator creator); 以id作为识别码注册生成器。函数、对象方法或仿函数都可以作为生成器。
bool Unregister(const IdentifierType& id); 取消注册
std::vector RegisteredIds(); 取得已注册的所有识别码
AbstractProduct* CreateObject(const IdentifierType& id);
AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1);
AbstractProduct* CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2);
...
按识别码id生成对象(调用对应的生成器)

示例代码

  1. #include 
  2. #include 
  3. #include 
  4. #include 
  5.  
  6. // 窗体基类
  7. struct IWidget{
  8.     virtual void printName() = 0;
  9.     virtual ~IWidget(){;}
  10. };
  11. // 定义窗体工厂,使用string区分各对象类型
  12. typedef Loki::Factory widget_factory_t;</iwidget, std::string>
  13. // 按钮窗体
  14. struct CButton : IWidget{
  15.     void printName()
  16.     {
  17.         std::cout << "CButton" << std::endl;
  18.     }
  19. };
  20. // 编辑框窗体
  21. struct CEdit : IWidget{
  22.     void printName()
  23.     {
  24.         std::cout << "CEdit" << std::endl;
  25.     }
  26. };
  27. // 列表框窗体
  28. struct CListBox : IWidget{
  29.     void printName()
  30.     {
  31.         std::cout << "CListBox" << std::endl;
  32.     }
  33. };
【上篇】
【下篇】

抱歉!评论已关闭.