想用C++实现类似Java的反射机制,参考网上的设计方案形成了如下代码:
基类声明和实现:
protocolui.h:
#ifndef PROTOCOLUI_H
#define PROTOCOLUI_H
#include<map>
#include <string>
class UIProtocolDev;
struct UIProtocolDevInfo;
typedef UIProtocolDev* (*_tfnCreateUI) (void);
class UIProtocolDev
{
static std::map<std::string, _tfnCreateUI> m_uiInfoMap;
public:
UIProtocolDev() {}
virtual ~UIProtocolDev() {}
static bool registerUI(UIProtocolDevInfo* pUiDevInfo);
static UIProtocolDev* CreateUI(std::string type);
};
struct UIProtocolDevInfo {
std::string _type;
_tfnCreateUI _fnCreateUI;
UIProtocolDevInfo(std::string const type, _tfnCreateUI fnCreateUI);
};
#endif //PROTOCOLUI_H
protocolui.cpp
#include "protocolui.h"
std::map<std::string, _tfnCreateUI> UIProtocolDev::m_uiInfoMap;
bool UIProtocolDev::registerUI(UIProtocolDevInfo *pUiDevInfo)
{
if (pUiDevInfo == NULL) return false;
m_uiInfoMap[pUiDevInfo->_type] = pUiDevInfo->_fnCreateUI;
return true;
}
UIProtocolDev *UIProtocolDev::CreateUI(std::string type/*, QObject *parent, logstream::ILogHost * const logHost, const char *strIdentifier*/)
{
if (m_uiInfoMap[type] != NULL) {
return m_uiInfoMap[type](/*parent, logHost, strIdentifier*/);
}
return NULL;
}
UIProtocolDevInfo::UIProtocolDevInfo(const std::string type, _tfnCreateUI fnCreateUI)
{
_type = type;
_fnCreateUI = fnCreateUI;
UIProtocolDev::registerUI(this);
}
继承类声明和实现:
uiprotocolserialport.h:
#ifndef UIPROTOCOLSERIALPORT_H
#define UIPROTOCOLSERIALPORT_H
#include "protocolui.h"
#include <QObject>
#include <string>
class Test : public UIProtocolDev
{
public:
Test() {}
virtual ~Test() {}
static UIProtocolDev* CreateUI(void)
{ return new Test(); }
private:
static UIProtocolDevInfo m_devinfo;
};
#endif // UIPROTOCOLSERIALPORT_H
uiprotocolserialport.cpp:
#include "uiprotocolserialport.h"
UIProtocolDevInfo Test::m_devinfo("Test",(_tfnCreateUI)(Test::CreateUI()));
main.cpp:
void main(void)
{
UIProtocolDev * pdev = UIProtocolDev::CreateUI("Test");
delete pdev;
}
使用MinGW-w64 4.9.2编译链接后,运行时报告程序崩溃;
尝试将uiprotocolserialport.h和uiprotocolserialport.cpp中的代码分别移动到uiprotocol.h和uiprotocol.cpp中后,程序正常执行并正常结束。
由此怀疑在继承类与基类不在相同的文件中时,MinGW-w64的GCC编译器没有正确的安排基类静态成员变量UIProtocolDev::m_uiInfoMap和继承类静态成员变量Test::m_devinfo的创建顺序,使得继承类的静态成员先于基类的静态成员创建,但由于继承类的静态成员构造函数在执行时需要使用基类的静态成员,这造成访问未初始化内存区的错误。
因此,请问:
1.如何控制不同文件之间各种类的静态成员对象的创建顺序呢?
2.若无法控制创建顺序,有没有变通的办法来实现类似JAVA的反射机制呢?