原理 利用 std::map存储构建构建类的功能对象,通过字符串查找后实现运行时创建字符串对象
优点,减少判断语句,可以通过维护一个字符串即可创建对象。不用写一串switch case语句。
扩展好,可以创建多个派生类对象而无需再次维护生成对象的工厂类。
直接上代码:main函数里面:
int main()
{
/*
* _CIN : 声明类可以通过字符串创建
* _CNEW : 通过字符串创建类
*/
//声明该类的可被字符串创建
_CIN(B)
_CIN(A)
_CIN(Item)
//使用:
cout << "还没有创建对象" << endl;
auto aClass = (Base*)_CNEW("A"); //生成类
aClass->print(); //通过接口调用
//当发生错误:
auto NULL_Class = (Base*)_CNEW("S"); //S这个类没有被声明到可以通过类名创建
system("pause");
//结束
}
声明可以被创建的对象,然后直接通过字符串调用得到该对象的对象指针
还没有创建对象
A被创建
10
Class name not "CIN" to the initialization list
These classes can be created :
[A,B,Item,]
请按任意键继续. . .
可以看见 是在get函数时才创建对象
这里主要运用了map ,抽象类 还有宏技术
原理很简单 用一个单例去管理类的工厂类,声明的本质就是创建工厂类和往创建功能类里面添加工厂
其实也可以通过继承创建类去实现返回即用,重写返回函数就可以了。但是这是具体需求,就有在创建吧。
直接上源码 单头文件即可运行
#ifndef _STR_NEW_CLASS
#define _STR_NEW_CLASS
#include <iostream>
#include <map>
#include <string>
namespace __CC{
class _CBase
{
public:
virtual void* getClass() = 0;
};
#define _CC(A)\
class _CBase##A : public __CC::_CBase\
{\
public:\
void* getClass()override {\
return new A();\
}\
};
class _Create
{
public:
static _Create& instance();
void* get(const std::string& str);
std::map<std::string, _CBase*> data;
private:
_Create() {}
};
//use
#define _CIN(A) _CC(A) __CC::_Create::instance().data[#A] = new _CBase##A;
#define _CNEW(str) __CC::_Create::instance().get(str)
//end
//实现
void* _Create::get(const std::string& str)
{
if (data.find(str) != data.end()) {
return data[str]->getClass();
}
std::cout << "Class name not \"CIN\" to the initialization list" << std::endl;
std::cout << " These classes can be created : " << std::endl;
std::cout << "[";
for (auto item : data) {
std::cout << item.first << ",";
}
std::cout << "]"<<std::endl;
return nullptr;
}
_Create& _Create::instance()
{
static _Create* ins = nullptr;
if (ins == nullptr) {
ins = new _Create;
}
return *ins;
}
}
#endif // !_STR_NEW_CLASS
主函数完整代码
// 字符串构造类.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <string>
#include <map>
#include "strNewClass.h"
using namespace std;
//一个普通的基类()其实应该叫接口
class Base {
public:
virtual void print() = 0;
};
//一个普通的实现
class A :public Base
{
public:
void print()override{cout << this->a << endl;}
A(const int& i) { a = i; }
A() { cout << "A被创建"<<endl; }
int a = 10;
};
//又一个普通的实现
class B : public Base
{
public:
void print()override{cout << this->a << endl;}
B(const float& i){ a = i; }
B() { cout << "B被创建"<<endl; }
float a = 20;
};
//更加普通的实现,就一个接口
class Item : public Base
{
public:
void print()override
{
cout << "我不知都呀" << endl;
}
};
int main()
{ /*
* 使用说明:
* 使用对象共两个: _CIN _CNEW
* _CIN : 声明类可以通过字符串创建
* _CIN(参数) 参数:为类的名称 (非字符串)
*
* _CNEW : 通过字符串创建类
* 返回值 _CNEW(参数) 返回值为(void*)的对象。参数为字符串("className")
* 具体使用案例如下
*/
//声明该类的可被字符串创建
_CIN(B)
_CIN(A)
_CIN(Item)
//由于比较底层 所以加了一个_ 下划线
//使用:
cout << "还没有创建对象" << endl;
auto aClass = (Base*)_CNEW("A"); //生成类
aClass->print(); //通过接口调用
//当发生错误:
auto NULL_Class = (Base*)_CNEW("S"); //S这个类没有被声明到可以通过类名创建
system("pause");
//结束
}