我目前正在研究开源C ++项目,以了解有关C ++的更多信息。 我看到的项目之一位于:
https://github.com/Myzilla-Web-Resources/OpenBlox/
我理解大部分源代码,但我不明白的是他如何使用预处理器来声明C ++类。
例如,
static_init.h
#define DECLARE_STATIC_INIT(ClassName) \
static void static_init_func(); \
static OpenBlox::static_init_helper ClassName##_static_init_helper
namespace OpenBlox{
class static_init_helper{
public:
static_init_helper(init_func_type f){
static_init::instance().add_init_func(f);
}
};
Instance.h
#define DECLARE_CLASS(Class_Name) \
virtual Instance* cloneImpl(); \
virtual QString getClassName(); \
virtual int wrap_lua(lua_State* L); \
DECLARE_STATIC_INIT(Class_Name); \
protected: \
static QString ClassName; \
static QString LuaClassName
Frame.h
namespace ob_instance{
class Frame: public GuiObject{
public:
Frame();
virtual ~Frame();
virtual void render();
DECLARE_CLASS(Frame);
};
}
#endif
请注意,Frame.h继承了所有Instance.h函数/处理器。 有人可以向我解释这是如何工作的吗?
答案 0 :(得分:2)
预处理器只是文本查找和替换,因此在您显示的Frame
定义中,预处理器首先看到DECLARE_CLASS(Frame)
并将其替换为DECLARE_CLASS
宏的内容,
namespace ob_instance{
class Frame: public GuiObject{
public:
Frame();
virtual ~Frame();
virtual void render();
virtual Instance* cloneImpl();
virtual QString getClassName();
virtual int wrap_lua(lua_State* L);
DECLARE_STATIC_INIT(Frame);
protected:
static QString ClassName;
static QString LuaClassName;
};
}
(我清理了格式,实际上整个替换文字在一行上。)
然后在它插入的文本之前备份,再次开始阅读,并看到DECLARE_STATIC_INIT(Frame)
并替换它:
namespace ob_instance{
class Frame: public GuiObject{
public:
Frame();
virtual ~Frame();
virtual void render();
virtual Instance* cloneImpl();
virtual QString getClassName();
virtual int wrap_lua(lua_State* L);
static void static_init_func();
static OpenBlox::static_init_helper Frame_static_init_helper;
protected:
static QString ClassName;
static QString LuaClassName;
};
}
(##
是token concatenation operator)
给你最后的Frame
课程定义。
正如Chris Beck在评论中所提到的,您可以使用-E
标志来gcc或clang让编译器输出预处理文件而不是编译它。