在宏之后恢复访问修饰符

use*_*028 5 c++ macros access-modifiers

为了声明代码库中许多类所需的方法列表,我们使用如下宏:

#define DECLARE_METHODS()             \
    public:                           \
        virtual void foo1(/*args*/);  \
        virtual void foo2(/*args*/);  \
        [...]                         \
    protected:                        \
        virtual void bar(/*args*/);   \
    public:
Run Code Online (Sandbox Code Playgroud)

通常这样使用:

class Class
{
public:
    Class();
    ~Class();

    DECLARE_METHODS();

    /*other public members*/

private:
    /*private members*/
};
Run Code Online (Sandbox Code Playgroud)

但众所周知,这样使用时会造成一些严重破坏:

class Class
{
public:
    Class();
    ~Class();

private:
    DECLARE_METHODS();

    /*private members*/
};
Run Code Online (Sandbox Code Playgroud)

...因为它偷偷地声明了对其下面所有内容的公共访问修饰符。

它已使用数千次,因此用 private: 替换最终的 public: 会太耗时,因为必须遍历几乎所有客户端才能移动宏或在适用时在其后打开一个公共访问修饰符。删除所有修饰符并使 bar() 不受保护不是一个选项。

有没有办法知道代码的特定部分正在使用哪个访问修饰符?是否可以断言该宏从未在非公共范围内使用,或者以某种方式记住并恢复宏末尾的正确访问修饰符?

Ric*_*ges 3

简短回答:否

原因:宏扩展在任何 c++ 开始被解释为 c++ 之前就已由预处理器完全完成。

这意味着预处理器对代码是盲目的 - 它可能是 java、c、文本,甚至 python(如果您没有注释它)并且预处理器会很乐意扩展宏。

您想要做的事情可以通过奇怪的重复模板模式来实现http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

例如,这就是 ATL 自动为您实现常见 COM 接口的方式。