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
风轻云淡 阅读(2116)
评论(0) 编辑 收藏 引用 所属分类:
C++