C++ 动态创建对象
2013-07-15 20:47
302 查看
转自:http://www.cnblogs.com/jisi5789/p/3190353.html
回顾前面的文章,实现了一个简单工厂模式来创建不同类对象,但由于c++没有类似new"Circle"之类的语法,导致CreateShape函
数中需要不断地ifelse地去判断,如果有多个不同类对象需要创建,显然这是很费神的,下面通过宏定义注册的方法来实现动态创
建对象。
Shape.h:
Shape.cpp:
DynBase.h:
DynTest.cpp:
在DynBase.h中#define了一个宏定义REGISTER_CLASS(class_name),且在Shape.cpp中调用宏定义,拿REGISTER_CLASS(Circle);
来说,程序编译预处理阶段会被替换成:
也即定义了一个新类,且由于含有static成员,则在main函数执行前先执行初始化,调用Register类构造函数,在构造函数中调用
DynObjectFactory::Register(name,func);即调用DynObjectFactory类的静态成员函数,在Register函数中通过map容器完成了
字符串与函数指针配对的注册,如mapCls_[name]=func;
进入main函数,调用DynObjectFactory::CreateObject("Circle"),CreateObject函数中通过string找到对应的函数指针
(NewInstance),并且调用后返回创建的对象指针,需要注意的是returnit->second();中it->second是函数指针,后面加括
号表示调用这个函数。对宏定义中的#,##用法不熟悉的可以参考这里。
这样当需要创建多个不同类对象的时候,就不再需要写很多ifelse的判断了。
参考:
C++primer第四版
EffectiveC++3rd
C++编程规范
回顾前面的
数中需要不断地ifelse地去判断,如果有多个不同类对象需要创建,显然这是很费神的,下面通过宏定义注册的方法来实现动态创
建对象。
Shape.h:
#ifndef_SHAPE_H_ #define_SHAPE_H_ classShape { public: virtualvoidDraw()=0; virtual~Shape(){} }; classCircle:publicShape { public: voidDraw(); ~Circle(); }; classSquare:publicShape { public: voidDraw(); ~Square(); }; classRectangle:publicShape { public: voidDraw(); ~Rectangle(); }; #endif//_SHAPE_H_
Shape.cpp:
#include"Shape.h" #include"DynBase.h" #include<iostream> usingnamespacestd; voidCircle::Draw() { cout<<"Circle::Draw()..."<<endl; } Circle::~Circle() { cout<<"~Circle..."<<endl; } voidSquare::Draw() { cout<<"Square::Draw()..."<<endl; } Square::~Square() { cout<<"~Square..."<<endl; } voidRectangle::Draw() { cout<<"Rectangle::Draw()..."<<endl; } Rectangle::~Rectangle() { cout<<"~Rectangle..."<<endl; } REGISTER_CLASS(Circle); REGISTER_CLASS(Square); REGISTER_CLASS(Rectangle);
DynBase.h:
#ifndef_DYN_BASE_H_ #define_DYN_BASE_H_ #include<map> #include<string> usingnamespacestd; typedefvoid*(*CREATE_FUNC)(); classDynObjectFactory { public: staticvoid*CreateObject(conststring&name) { map<string,CREATE_FUNC>::const_iteratorit; it=mapCls_.find(name); if(it==mapCls_.end()) return0; else returnit->second();//func(); } staticvoidRegister(conststring&name,CREATE_FUNCfunc) { mapCls_[name]=func; } private: staticmap<string,CREATE_FUNC>mapCls_; }; //g++ //__attribute((weak)) __declspec(selectany)map<string,CREATE_FUNC>DynObjectFactory::mapCls_; //头文件被包含多次,也只定义一次mapCls_; classRegister { public: Register(conststring&name,CREATE_FUNCfunc) { DynObjectFactory::Register(name,func); } }; #defineREGISTER_CLASS(class_name)\ classclass_name##Register{\ public:\ staticvoid*NewInstance()\ {\ returnnewclass_name;\ }\ private:\ staticRegisterreg_;\ };\ Registerclass_name##Register::reg_(#class_name,class_name##Register::NewInstance) //CircleRegister #endif//_DYN_BASE_H_
DynTest.cpp:
#include"Shape.h" #include"DynBase.h" #include<iostream> #include<vector> #include<string> usingnamespacestd; voidDrawAllShapes(constvector<Shape*>&v) { vector<Shape*>::const_iteratorit; for(it=v.begin();it!=v.end();++it) { (*it)->Draw(); } } voidDeleteAllShapes(constvector<Shape*>&v) { vector<Shape*>::const_iteratorit; for(it=v.begin();it!=v.end();++it) { delete(*it); } } intmain(void) { vector<Shape*>v; Shape*ps; ps=static_cast<Shape*>(DynObjectFactory::CreateObject("Circle")); v.push_back(ps); ps=static_cast<Shape*>(DynObjectFactory::CreateObject("Square")); v.push_back(ps); ps=static_cast<Shape*>(DynObjectFactory::CreateObject("Rectangle")); v.push_back(ps); DrawAllShapes(v); DeleteAllShapes(v); return0; }
在DynBase.h中#define了一个宏定义REGISTER_CLASS(class_name),且在Shape.cpp中调用宏定义,拿REGISTER_CLASS(Circle);
来说,程序编译预处理阶段会被替换成:
classCircleRegister{ public: staticvoid*NewInstance() { returnnewCircle; } private: staticRegisterreg_; };
RegisterCircleRegister::reg_("Circle",CircleRegister::NewInstance);
也即定义了一个新类,且由于含有static成员,则在main函数执行前先执行初始化,调用Register类构造函数,在构造函数中调用
DynObjectFactory::Register(name,func);即调用DynObjectFactory类的静态成员函数,在Register函数中通过map容器完成了
字符串与函数指针配对的注册,如mapCls_[name]=func;
进入main函数,调用DynObjectFactory::CreateObject("Circle"),CreateObject函数中通过string找到对应的函数指针
(NewInstance),并且调用后返回创建的对象指针,需要注意的是returnit->second();中it->second是函数指针,后面加括
号表示调用这个函数。对宏定义中的#,##用法不熟悉的可以参考
这样当需要创建多个不同类对象的时候,就不再需要写很多ifelse的判断了。
参考:
C++primer第四版
EffectiveC++3rd
C++编程规范
相关文章推荐
- c++对象的动态创建与释放
- 从零开始学C++之模板(四):用模板实现单例模式(线程安全)、模板方式实现动态创建对象
- 不可或缺 Windows Native (19) - C++: 对象的动态创建和释放, 对象的赋值和复制, 静态属性和静态函数, 类模板
- 分享:Thinking in C++ Notes: 动态对象创建
- C++动态创建对象
- 仿MFC实现c++的按名动态创建对象功能
- 三十一、反射、C++动态对象创建实现
- c++のstatic静态成员、对象的动态创建和释放
- C++ 用new动态创建对象
- 仿MFC实现c++按名动态创建对象之续(瘦身以及解决其在dll中使用的问题)
- C++ 用new动态创建对象
- C++实现反射(根据类名动态创建对象)
- 从零开始学C++之动态创建对象
- 从零开始学C++之模板(四):用模板实现单例模式(线程安全)、模板方式实现动态创建对象
- C++ 类工厂实现动态对象创建
- 从零开始学C++之动态创建对象
- c++动态的创建对象数组
- C++实现只能动态或者静态创建对象
- 读取配置文件动态创建对象[C++]
- C++动态创建对象应用技术讲解