C++学习笔记05 由类名创建对象

C++学习笔记05 由类名创建对象
1.应用:
也许需要一个脚本,脚本中有一个参数传递类名,你需要通过类名来动态的创建这个对象,这时候就需要动态创建了

 2.原理:
C++不是动态语言,所以没法从语言机制上实现类的动态创建,但这样的需求却有可能存在,一个类似的例子便是MFC中CWnd类的Create方法,其第一个参数为Window Class的名字,这就允许用户通过class的名字来创建相应的窗口。
 要想实现这一点, 必须有一个“管理中心”,用于登记类的名字,并且通过名字能够调用对应的创建方法来创建相应的实例。结合类工厂的设计思想,这里我们让一套继承体系中的基类作为“管理中心”,由它来维护所有派生类的必要信息,包括类名和工厂函数,这二者必须建立起映射关系,map是不错的选择。定义了一个派生类后,它就自动向基类进行注册

3.实现:
可以用宏来代替:
/*
    实现原理:
    基类里面用map管理所有需要动态创建 【类名-创建对象的函数指针】
    基类声明中需要添加 DECLEAR_DYNCRT_BASE 宏,cpp实现中要添加 IMPLEMENT_DYNCRT_BASE 宏
    派生类声明中需要添加 DECLEAR_DYNCRT_CLASS 宏,cpp实现中要添加 IMPLEMENT_DYNCRT_CLASS 宏
    派生类宏中创建了一个全局对象向基类map中注册【类名-创建对象的函数指针】
    
*/
#include <map>


//  声明具有动态创建的基类
#define DECLEAR_DYNCRT_BASE(base) \
public: \
typedef  base* (*ClassGen)(); \
static  void _register( const  char* class_name, ClassGen class_gen) \
{ \
    class_set.insert(std::map< const  char*, ClassGen>::value_type(class_name, class_gen)); \
} \
static  base* create( const  char* class_name) \
{ \
    std::map< const  char*, ClassGen>::iterator it = class_set.find(class_name);   \
     if (it != class_set.end()) \
         return (it->second)(); \
     return NULL; \
} \
protected: \
static std::map< const  char*, ClassGen> class_set;

//  用于实现基类
#define IMPLEMENT_DYNCRT_BASE(base) \
std::map< const  char*,  base::ClassGen>  base::class_set;


//  用于声明一个能够被动态创建的类(用一个全局对象进行注册)
#define DECLEAR_DYNCRT_CLASS(derived, base) \
public: \
     struct derived##register \
    { \
        derived##register() \
        { \
             static  bool bRegister =  false; \
             if (!bRegister) \
            { \
                 base::_register(#derived, _CreateObjectByName); \
                bRegister =  true; \
            } \
        } \
    }; \
     static  base* _CreateObjectByName() \
    { \
         return  new derived; \
    }


//  用于实现一个能被动态创建的类
#define IMPLEMENT_DYNCRT_CLASS(derived) \
     static derived::derived##register _##derived##global_object;

我们需要做的就是是哦那个这四个宏
附加上测试代码:
//  测试实例:
class Base
{
    DECLEAR_DYNCRT_BASE(Base)
    DECLEAR_DYNCRT_CLASS(Base, Base)
public:
     virtual  void Print()
    {
        std::cout << "This is base!" << std::endl;
    }
};

IMPLEMENT_DYNCRT_BASE(Base)
IMPLEMENT_DYNCRT_CLASS(Base)


class Derived :  public Base
{
    DECLEAR_DYNCRT_CLASS(Derived, Base)
public:
     virtual  void Print()
    {
        cout << "This is derived!" << endl;
    }
};
IMPLEMENT_DYNCRT_CLASS(Derived)


int main()
{
    Base*  base = Base::create("Base");
     if ( base)
         base->Print();

    system("pause");
     return 0;
}


参考地址: http://blog.csdn.net/freefalcon/article/details/109275 


你可能感兴趣的:(C++学习笔记05 由类名创建对象)