随笔 - 132  文章 - 51  trackbacks - 0
<2012年8月>
2930311234
567891011
12131415161718
19202122232425
2627282930311
2345678

常用链接

留言簿(7)

随笔分类

随笔档案

文章分类

文章档案

cocos2d-x

OGRE

OPenGL

搜索

  •  

最新评论

阅读排行榜

评论排行榜

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 


posted on 2012-08-30 12:15 风轻云淡 阅读(2058) 评论(0)  编辑 收藏 引用 所属分类: C++

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