c++插件技術初步--動態創建對象

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章