由于最近工作中用到工厂模式来创建不同的窗口对象在主窗口中显示, 以前遇到类似的情况我都是把所有需要创建的窗口类头文件都包含到主窗口MainWnd.cpp中, 这样每新增一个窗口, 就需要修改 MainWnd.cpp 。MainWnd.cpp 也就需要重新编译。?后来百度了下c++反射, 有用Qt 元对象机制的(Qt继承自QObject 的类是可以支持反射的); 有用模版实现的类工厂, 然后需要反射的类从该类继承; 也有模仿MFC 的(需要在类的声明和实现中加入相关宏)...? 感觉都有点麻烦。
后来再百度下有没有用 c++11, 或者 boost 实现的, 但好像没找到, 于是今天我闲着无聊就自己写一个基于C++11语法的类名反射。 最终成型后, 功能对于我来说已经满足。
用法是:
1> 在需要反射的类cpp 中调用宏 ReflectRegister 注册子类
2> 在策略函数中, 包含基类头文件,??然后根据子类的类名创建对象。
代码如下:
/* @file ObjFactory.h
* @brief 根据子类名创建对象。可注册构造函数参数个数任意的类
*
* 用法:假设 BaseShape 有 2 个派生类: Rectangle 和 Triangle 。 3个类分别在不同的文件中
* , BaseShape 有个纯虚函数 virtual void draw() = 0;
* @code:
* // BaseShape.h
* class BaseShape
{
public:
virtual void draw() = 0;
};
// Rectangle.cpp
#include "BaseShape.h"
#include "ObjFactory.h"
ReflectRegister(Rectangle) // 注册矩形类
class Rectangle : public BaseShape
{
public:
Rectangle()
{}
void draw() override
{
qDebug("%s", qPrintable("I'm Rectangle"));
}
};
// Triangle.cpp
#include "BaseShape.h"
#include "ObjFactory.h"
ReflectRegister(Rectangle) // 注册三角形类
class Triangle : public BaseShape
{
public:
Triangle()
{}
void draw() override
{
qDebug("%s", qPrintable("I'm Triangle"));
}
};
// main.cpp
#include "BaseShape.h" // 只用包含基类头
int main()
{
BaseShape* pBase;
pBase = ObjFactory::createObj<BaseShape>("Rectangle");
if (pBase != nullptr)
pBase->draw();
pBase = ObjFactory::createObj<BaseShape>("Triangle");
if (pBase != nullptr)
pBase->draw();
}
@endcode
* @author zhoumanman888@126.com
* @date 2021/7/24
*/
#ifndef ObjFactory_H
#define ObjFactory_H
#include <map>
#include <string>
/// 需要反射的类使用该宏注册
#ifndef ReflectRegister
#define ReflectRegister(YourClass, ...) \
const int __type = ObjFactory::_RegClsFactoryFunc(#YourClass, (ObjFactory::_FunctionFactory)&_CreateObjFactory<YourClass, ##__VA_ARGS__>);
#endif
/// 对象工厂,根据类名创建
class ObjFactory
{
public:
/// 可以保存带任何类型参数的函数指针
typedef void*(*_FunctionFactory)();
/// 根据类名创建 BaseClass 子类的对象
template<class BaseClass, typename ...ArgType>
static BaseClass* createObj(std::string className, ArgType... arg)
{
typedef BaseClass*(*_CreateFactory)(ArgType...);
auto& _funcMap = _GetStaticFuncMap();
auto iFind = _funcMap.find(className);
if (iFind == _funcMap.end())
return nullptr;
else
return reinterpret_cast<_CreateFactory>(_funcMap[className])(arg...);
}
/// 注册“创建类的对象的工厂函数”
static int _RegClsFactoryFunc(std::string className, _FunctionFactory func)
{
_GetStaticFuncMap()[className] = func;
return 0;
}
private:
/// 获取 函数名==>函数指针 的映射。
static std::map<std::string, _FunctionFactory>& _GetStaticFuncMap()
{
static std::map<std::string, _FunctionFactory> _classMap;
return _classMap;
}
};
/// 对象创建模版函数, 用到了 c++11 的可变参数
template<class YourClass, typename ...ArgType>
YourClass* _CreateObjFactory(ArgType... arg)
{
return new YourClass(arg...);
}
#endif // ObjFactory_H
|