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