c++ 36 对象动态创建

shape.h

#ifndef _SHAPE_H_
#define _SHAPE_H_
class Shape
{
public:
	virtual void Draw()=0;
	virtual ~Shape(){};
};
class Circle:public Shape  
{  
public:  
    void Draw() ;
	~Circle();
    
};  
class Square:public Shape  
{  
public:  
    void Draw();
	~Square();
};  
class Rectangle :public Shape
{
public:
	void Draw();
	~Rectangle();
};

#endif

DynBase.h

#ifndef _DYN_BASE_H_
#define _DYN_BASE_H_
#include <string>
#include <iostream>
#include <map>
using namespace std;
typedef void* (*CREATE_FUNC)();//定义函数指针

class DynObjectFactory
{
public:
	static void*  CreateObject(const string& name)//不知道对象的类型void* 
	{
		map<string,CREATE_FUNC>::const_iterator it;
		it=mapCls_.find(name);
		if(it==mapCls_.end())
		{
		   return 0;
		}else
		{
			return it->second();
		}
	}
	static void  Register(const string& name,CREATE_FUNC func)
	{
		mapCls_[name]=func;//插入一条记录
	}
private:
	static map<string,CREATE_FUNC> mapCls_;//创建的方法保存在map 容器当中了。
};
_declspec(selectany) map<string,CREATE_FUNC> DynObjectFactory::mapCls_;
class Register
{
public:
	Register(const string& name,CREATE_FUNC func)
	{
		DynObjectFactory::Register(name,func);
	}
};
//宏的定义
#define REGISTER_CLASS(class_name)\
class class_name##Register{\
public:\
   static void* NewInstance()\
   {\
      return   new class_name;\
   }\
private:\
  static Register reg_;\
};\
	Register class_name##Register::reg_(#class_name,class_name##Register::NewInstance);
#endif

cpp main

//动态创建对象 对原有的类不做任何改变,只需要增加一个宏就能够实现动态创建
#include "Shape.h"
#include <iostream>
#include <string>
#include <vector>
#include "DynBase.h"
using namespace std;
void DrawAllShape(const vector<Shape*>& v)  
{  
    vector<Shape*>::const_iterator it;  
    for(it=v.begin();it!=v.end();++it)  
    {  
        (*it)->Draw();  //*it 就是Shape*  
    }  
}  
void DeleteAllShape(const vector<Shape*>& v)  
{  
    vector<Shape*>::const_iterator it;  
    for(it=v.begin();it!=v.end();++it)  
    {  
        delete(*it);  
    }  
}
int main(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("Rentanle"));  
        v.push_back(ps);*/  
    /*ps=new Circle;  
    v.push_back(ps);  
    ps=new Square;  
    v.push_back(ps);  
    ps=new Rentanle;  
    v.push_back(ps);*/  
    //能够适应未来的变化  
    DrawAllShape(v);  
      
    DeleteAllShape(v);
  return 0;
}

shape.cpp

#include "Shape.h"
#include <iostream>
#include "DynBase.h"
using namespace std;

void Circle:: Draw()
{
	cout<<"Circle::Draw.."<<endl;
}
Circle::~Circle()
{
   cout<<"~Circle.."<<endl;
}
void Square::Draw()
{
   cout<<"Square::Draw"<<endl;
}
Square::~Square()
{
   cout<<"~Square.."<<endl;
}
void Rectangle::Draw()
{
   cout<<"Rectangle::Draw"<<endl;
}
Rectangle::~Rectangle()
{
   cout<<"~Rectangle.."<<endl;
}
//宏
REGISTER_CLASS(Circle);
REGISTER_CLASS(Square);
REGISTER_CLASS(Rectangle);

//=====下面是分析----
//#define REGISTER_CLASS(class_name)\
//class class_name##Register{\
//public:\
//   static void* NewInstance()\
//   {\
//      return   new class_name;\
//   }\
//private:\
//  static Register reg_;\
//};\
//	Register class_name##Register::reg_(#class_name,class_name##Register::NewInstance);
//==================== 扩展出来的结果
//class CircleRegister
//{
//public:
//	static void* NewInstance()
//	{
//	    return new Circle;
//	}
//private :
//	static Register reg_;//声明
//};
定义 static 程序运行时候,就会调用他的构造函数
//Register CircleRegister::reg_("Circle",CircleRegister::NewInstance);


部分语言摘抄:

http://www.cnblogs.com/sevenyuan/p/3191933.html

也即定义了一个新类,且由于含有static 成员,则在main函数执行前先执行初始化,调用Register类构造函数,在构造函数中调用

DynObjectFactory::Register(name, func); 即调用DynObjectFactory 类的静态成员函数,在Register函数中通过map容器完成了

字符串与函数指针配对的注册,如mapCls_[name] = func;

进入main函数,调用DynObjectFactory::CreateObject("Circle") ,CreateObject函数中通过string找到对应的函数指针

(NewInstance),并且调用后返回创建的对象指针,需要注意的是 return it->second(); 中it->second 是函数指针,后面加括

号表示调用这个函数。对宏定义中的#,##用法不熟悉的可以参考这里

这样当需要创建多个不同类对象的时候,就不再需要写很多ifelse的判断了。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值