/*
根据字符串运行时刻动态产生类对象
【编译运行环境】
Windows/ VC6
Linux  / g++
【使用方法】
1. 首先需要定义类,比如 B 从 A 派生出来
2. 调用以下语句注册B类:
    DYN_DECLARE(B);
3. 此后只需用类名对应的字符串就可以创建该类的对象:
    A * p1 = (A *) DYN_CREATE("B");
    
    此时创建的是 B 的对象(downcast)
4. 如果某个类未注册(通过DYN_DECLARE),DYN_CREATE 返回NULL指针
*/
/* ************************************************************************* */
/*                              dynclass.h                                   */
/*   使用的时候#include "dynclass.h",在类的声明后使用DYNCLASS(类名)注册 */  
/* ************************************************************************* */

#ifndef __DYNAMIC_H__
#define __DYNAMIC_H__

#include <cstdio>
#include < string>
#include <typeinfo>
#include <cstring>

#if !defined ( DYN_DECLARE )
#define DYN_DECLARE(class_name) DYN_CLASS::CFactory<class_name> class_name
#endif

#if !defined ( DYN_CREATE )
#define DYN_CREATE(class_name)   DYN_CLASS::Create(class_name)
#endif


namespace DYN_CLASS
{
     /*  create object by class name  */
     void * Create(  const  char * class_name );

     /*  interface of class factory */
     class CAbstractFactory
    {
     public:
         virtual  void * Create(  const  char * class_name ) = 0;
    };

     /*  list of class factory  */
     class CFactoryList
    {
        friend  void * Create(  const  char * class_name );
private:
         static CFactoryList * _head;
        CFactoryList        * m_next;
        CAbstractFactory    * m_item;
     public:
        CFactoryList( CAbstractFactory * fact );
         virtual ~CFactoryList(  void );
    };

     /*  ctor of CFactoryList, add a class factory to list  */
    inline CFactoryList::CFactoryList( CAbstractFactory * fact )
                            : m_item( fact )
    {
        m_next = _head;
        _head =  this;
    }

#if defined ( _MSC_VER )
     /*  disable warning for the following line : CFactory( void ): m_item( this ) {}  */
    #pragma warning(disable : 4355)
#endif

     /*  realization of class factory  */
    template < class t>
     class CFactory:  public CAbstractFactory
    {
         static t     _object;
        CFactoryList m_item;

     public:

/*  add itself to list of class factory when constructed  */
        CFactory(  void ) : m_item(  this ) {}

         virtual ~CFactory() {}

/*  create object of this class if matched  */
         void * Create(  const  char * class_name )
        {
    std:: string strClassName;

#if defined (WIN32 )
    strClassName = ( "class " );
#else
             char szSize[4] = {0};
            sprintf(szSize, "%d", strlen(class_name) );
    strClassName = szSize;
#endif
            strClassName += class_name;

             /*  RTTI support  */
             return !strcmp( typeid(_object).name(), strClassName.c_str() )
                    ? ( void*)(  new t ) : 0 ;

        }
    };
}
#endif /* __DYNAMIC_H__ */



/* ************************************************************************* */
/*                              dynclass.cpp                                 */
/* ************************************************************************* */

#include "dynclass.h"

namespace DYN_CLASS
{
    CFactoryList * CFactoryList::_head = 0;

     void *Create(  const  char * class_name )
    {
         void * new_object = 0;
         const CFactoryList * cur = CFactoryList::_head;

         for( ; cur ; cur = cur->m_next )
{
      /*  if class_name matched, object will then be created and returned  */
             if( new_object = cur->m_item->Create(class_name) )
     {
                 break;
     }
}

         return new_object;
    }

     /*  delete linkage from CFactoryList when some class factory destroyed  */
    CFactoryList::~CFactoryList(  void )
    {
        CFactoryList ** m_nextp = &CFactoryList::_head;

         for( ; *m_nextp ; m_nextp = &(*m_nextp)->m_next )
             if( *m_nextp ==  this )
            {
                *m_nextp = (*m_nextp)->m_next;
                 break;
            }
    }
}
// 改天再给范列了,有事情了