Singleton就是保证一个类只有一个实例,在Ogre里面有很多Singleton的例子,几乎所有的Manager都是Singleton的实例。比较下Gof里面的Singleton的实现和loki中的Singleton的实现,Ogre的Singleton算是比较简单的。Gof中实现一般是把类的构造函数给Private了然后再加上static的变量和函数实现的。下面来具体看一下Ogre中的Singleton
 1#ifndef _SINGLETON_H__
 2#define _SINGLETON_H__
 3
 4namespace Ogre {
 5    template <typename T> class Singleton
 6    {
 7    protected:
 8        static T* ms_Singleton;
 9    public:
10        Singleton( void )
11        {
12            assert( !ms_Singleton );
13#if defined( _MSC_VER ) && _MSC_VER < 1200     
14            int offset = (int)(T*)1 - (int)(Singleton <T>*)(T*)1;
15            ms_Singleton = (T*)((int)this + offset);
16#else
17        ms_Singleton = static_cast< T* >this );
18#endif
19        }

20        ~Singleton( void )
21            {  assert( ms_Singleton );  ms_Singleton = 0;  }
22        static T& getSingleton( void )
23        {    assert( ms_Singleton );  return ( *ms_Singleton ); }
24        static T* getSingletonPtr( void )
25        return ms_Singleton; }
26    }
;
27}

28#endif

先来看一下Singleton的构造函数是Public的,这样不是大家都能用了?往下看,第一句就是assert(!ms_Singleton); 如果ms_Singleton不是0的话,也就是Singleton<T>已经有了一个自己的对象,那么程序就死翘翘了。如果是0,那么跳过13-16行,直接看17行的
ms_Singleton = static_cast<T*>(this),有没有注意到那个this,出现在这里有点诡异。这里是构造函数,对象的初始化还没有完成呢,那么this指向的东西是什么呢?先来看一下怎么生成一个Singleton的实例。

#include <iostream>
#include 
"singleton.h"
class Intsin:public Singleton< Intsin >
{
public:
     Intsin(
int tmp):t(tmp){std::cout << "build"<< std::endl;}
    
~Intsin(){std::cout << "destory"<< std::endl;}
    print()
{std::cout << t << std::endl;}
private:
    
int t;
}
;

template
<> Intsin* Singleton< Intsin > ::ms_Singleton = 0;

int main()
{
    Intsin
* a;
    a 
=  new Intsin(3);
    a
->print();
    delete a;
    system(
"pause");
}
上面是一个超简单的实现,主要来看一下a = new Intsin(3);这里系统先按照Intsin的大小分配一块内存出来,然后调用Intsin的构造函数,当然要先运行基类Singleton<Intsin>的构造函数,这时Singleton构造函数的this指针应该是指向刚才分配的那个Intsin对象的地址了,虽然里面的东西不完整,但是this指向的对象的基本框架已经有了。所以可以这样使用它。要想知道这时this指针指向的对象到底有什么东西,什么东西没有,可以搜索一下“构造函数的this”看一下有关文章。当构造函数完成的时候,new返回一个指针。这样就完成了一个实例了。
下面来说一下,这个类什么东西没做,用的时候要注意什么。
1.当要实例化一个已经被实例化的类时,会有assert(!ms_Singleton);所以一定不能这样做。
2.对一个实例的指针两次调用delete也是让程序崩溃的好办法
3.Singleton<>不负责对象的解析,所以一定要记得自己delete,记住就一次。
总结下,这里的Singleton的实现比较简单,也很好用,但是程序员要负责的东西比较多。在Ogre中几乎所有的Singleton对象都是在root里面new和delete的。
就这么多吧。

Feedback

# re: Ogre实现的Singleton——设计模式  回复  更多评论   

2009-01-12 02:58 by killercat
你还没有理解 OGRE 的 Singleton。

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理


posts - 2, comments - 4, trackbacks - 0, articles - 0

Copyright © 空心菜