当先锋百科网

首页 1 2 3 4 5 6 7

c++动态创建对象,思路:按照对象名称来动态创建,将对象名称与创建函数一起保存到map中,创建时通过map来查找返回;

#pragma once
#include "DynCreateBase.h"
#include <iostream>
using namespace std;

class Shape
{
public:
	Shape() = default;
	virtual void Draw() = 0;
	~Shape() {}
};

class Rect :public Shape
{
public:
	Rect() :Shape() {}
	~Rect() {}
	virtual void Draw() override
	{
		std::cout << " Draw Rect" << std::endl;
	}
};

class Circle :public Shape
{
public:
	Circle() :Shape() {}
	~Circle() {}
	virtual void Draw() override
	{
		std::cout << "Draw Circle" << std::endl;
	}
};

class Triangle :public Shape
{
public:
	Triangle() :Shape() {}
	~Triangle() {}
	virtual void Draw() override
	{
		std::cout << "Draw Triangle" << std::endl;
	}
};

REGISTER_OBJ(Rect);    //只需要通过宏来注册创建函数即可
REGISTER_OBJ(Circle); 
REGISTER_OBJ(Triangle);

//动态创建类的实现,需要两个接口,create与register,静态成员变量 map,代码如下

 

 

#pragma once
#include <map>
#include <functional>


typedef void *(*CreateFunc)();

class DynCreateBase
{
public:

	DynCreateBase() =default;
	~DynCreateBase() =default;

	static void* DynamicCreate(const std::string &strName)
	{
		auto it = m_createMap.find(strName);
		if (it != m_createMap.end())
		{
			return (void*)(it->second());
		}
		return nullptr;
	}

	static void RegisterCreate(const std::string &strName, CreateFunc func)
	{
		m_createMap[strName] = func;
	}
private:
	static std::map<std::string, CreateFunc> m_createMap;
};

按照上面REGISTER_OBJ(Rect)宏完成自动注册的功能,

class Register
{
public:
	Register(const std::string &str, CreateFunc func)
	{
		DynCreateBase::RegisterCreate(str, func);
	}
};

#define  REGISTER_OBJ(class_name) \
class class_name##Register { \
public:						\
	static void *newInstatnce()	\
	{		\
		return	new class_name;\
	}							\
private:						\
	static Register m_reg;	\
};							\
__declspec(selectany) Register	class_name##Register::m_reg(#class_name, &class_name##Register::newInstatnce);

核心技巧为在宏中通过static Register m_reg;   来自动完成注册,通过static 自动构造函数过程中,传递name与注册函数来达到自动注册的目的

 

 

完成代码 shape.h

#pragma once
#include "DynCreateBase.h"
#include <iostream>
using namespace std;

class Shape
{
public:
	Shape() = default;
	virtual void Draw() = 0;
	~Shape() {}
};

class Rect :public Shape
{
public:
	Rect() :Shape() {}
	~Rect() {}
	virtual void Draw() override
	{
		std::cout << " Draw Rect" << std::endl;
	}
};

class Circle :public Shape
{
public:
	Circle() :Shape() {}
	~Circle() {}
	virtual void Draw() override
	{
		std::cout << "Draw Circle" << std::endl;
	}
};

class Triangle :public Shape
{
public:
	Triangle() :Shape() {}
	~Triangle() {}
	virtual void Draw() override
	{
		std::cout << "Draw Triangle" << std::endl;
	}
};

REGISTER_OBJ(Rect);
REGISTER_OBJ(Circle); 
REGISTER_OBJ(Triangle);

DynCreateBase.h自动构造与注册定义类

#pragma once
#include <map>
#include <functional>


typedef void *(*CreateFunc)();

class DynCreateBase
{
public:

	DynCreateBase() =default;
	~DynCreateBase() =default;

	static void* DynamicCreate(const std::string &strName)
	{
		auto it = m_createMap.find(strName);
		if (it != m_createMap.end())
		{
			return (void*)(it->second());
		}
		return nullptr;
	}

	static void RegisterCreate(const std::string &strName, CreateFunc func)
	{
		m_createMap[strName] = func;
	}
private:
	static std::map<std::string, CreateFunc> m_createMap;
};

__declspec(selectany) std::map<std::string, CreateFunc> DynCreateBase::m_createMap;

class Register
{
public:
	Register(const std::string &str, CreateFunc func)
	{
		DynCreateBase::RegisterCreate(str, func);
	}
};

#define  REGISTER_OBJ(class_name) \
class class_name##Register { \
public:						\
	static void *newInstatnce()	\
	{		\
		return	new class_name;\
	}							\
private:						\
	static Register m_reg;	\
};							\
__declspec(selectany) Register	class_name##Register::m_reg(#class_name, &class_name##Register::newInstatnce);

测试代码

#include <iostream>
#include <vector>
#include "shape.h"
#include "DynCreateBase.h"

int main()
{

	std::vector<Shape* >vec;

	vec.push_back((Shape*)DynCreateBase::DynamicCreate("Rect"));


	for (auto var:vec)
	{
		var->Draw();
	}
	system("pause");
	return 0;
}