C ++预处理器如何工作?

时间:2016-08-06 22:14:22

标签: c++ c-preprocessor

我目前正在研究开源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函数/处理器。 有人可以向我解释这是如何工作的吗?

1 个答案:

答案 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让编译器输出预处理文件而不是编译它。