可先參考:鏈接
問(wèn)題引入
如何根據(jù)一個(gè)字符串(類(lèi)的名稱(chēng))抱完,創(chuàng)建出一個(gè)對(duì)象
當(dāng)我們獲得了一個(gè)string str = "class_name"
蛤签,那么如何根據(jù)這個(gè)str
來(lái)創(chuàng)建一個(gè)對(duì)象有咨?這時(shí)候就需要用到反射。個(gè)人對(duì)反射的簡(jiǎn)單理解就是一個(gè)字面量來(lái)動(dòng)態(tài)創(chuàng)建出一個(gè)對(duì)象,并可獲取對(duì)象的成員信息陵且。Java和C#都有完整的反射機(jī)制杜顺,而C++至今還沒(méi)有财搁,只能自己動(dòng)手實(shí)現(xiàn)
實(shí)現(xiàn)思路
- 可以用一個(gè)
map
來(lái)存儲(chǔ)類(lèi)名-構(gòu)造函數(shù)這樣的鍵值對(duì),每新增一個(gè)類(lèi)躬络,就在這個(gè)map
“注冊(cè)”一個(gè)鍵值對(duì) - 因?yàn)檫@個(gè)
map
是一個(gè)全局都會(huì)用到的尖奔,所以可以使用單例模式 - 在進(jìn)入
main
函數(shù)之前,這個(gè)map
就應(yīng)該生成好穷当,即每一個(gè)類(lèi)在實(shí)例化之前就執(zhí)行了“注冊(cè)”的代碼提茁,那怎么在main
函數(shù)之前就執(zhí)行“注冊(cè)”代碼?答案可參見(jiàn)下面的代碼實(shí)現(xiàn)
代碼實(shí)現(xiàn)
#include <iostream>
#include <map>
#include <memory>
#define FUNC function<void*(void)>
using namespace std;
class Reflector
{
private:
map<std::string, FUNC>objectMap;
static shared_ptr<Reflector> ptr;
public:
void* CreateObject(const string &str)
{
for (auto & x : objectMap)
{
if(x.first == str)
return x.second();
}
return nullptr;
}
void Register(const string &class_name, FUNC && generator)
{
objectMap[class_name] = generator;
}
static shared_ptr<Reflector> Instance()
{
if(ptr == nullptr)
{
ptr.reset(new Reflector());
}
return ptr;
}
};
shared_ptr<Reflector> Reflector::ptr = nullptr;
class RegisterAction
{
public:
RegisterAction(const string &class_name, FUNC && generator)
{
Reflector::Instance()->Register(class_name, forward<FUNC>(generator));
}
};
#define REGISTER(CLASS_NAME) \
RegisterAction g_register_action_##CLASS_NAME(#CLASS_NAME, []()\
{\
return new CLASS_NAME(); \
});
class Base
{
public:
explicit Base() = default;
virtual void Print()
{
cout << "Base" << endl;
}
};
REGISTER(Base);
class DeriveA : public Base
{
public:
void Print() override
{
cout << "DeriveA" << endl;
}
};
REGISTER(DeriveA);
class DeriveB : public Base
{
public:
void Print() override
{
cout << "DeriveB" << endl;
}
};
REGISTER(DeriveB);
int main()
{
shared_ptr<Base> p1((Base*)Reflector::Instance()->CreateObject("Base"));
p1->Print();
shared_ptr<Base> p2((Base*)Reflector::Instance()->CreateObject("DeriveA"));
p2->Print();
shared_ptr<Base> p3((Base*)Reflector::Instance()->CreateObject("DeriveB"));
p3->Print();
}
上述代碼中的Reflector
使用了單例模式馁菜,維護(hù)一個(gè)存儲(chǔ)[類(lèi)名: 構(gòu)造器]的map
茴扁,每新增一個(gè)類(lèi),就會(huì)通過(guò)宏REGISTER
來(lái)為這個(gè)新增一個(gè)構(gòu)造器(其實(shí)就是一個(gè)lambda表達(dá)式汪疮,使用new
返回一個(gè)指針)峭火,并用這個(gè)構(gòu)造器和類(lèi)名生成一個(gè)RegisterAction
實(shí)例,而在RegisterAction
的構(gòu)造函數(shù)中進(jìn)行了“注冊(cè)”智嚷,即通過(guò)實(shí)例化一個(gè)RegisterAction
在main
函數(shù)之前完成了注冊(cè)