C++ 在宏之后恢复访问修饰符

C++ 在宏之后恢复访问修饰符,c++,macros,access-modifiers,C++,Macros,Access Modifiers,为了声明代码库中许多类所需的方法列表,我们使用如下宏: #define DECLARE_METHODS() \ public: \ virtual void foo1(/*args*/); \ virtual void foo2(/*args*/); \ [...] \ protected:

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

#define DECLARE_METHODS()             \
    public:                           \
        virtual void foo1(/*args*/);  \
        virtual void foo2(/*args*/);  \
        [...]                         \
    protected:                        \
        virtual void bar(/*args*/);   \
    public:
通常是这样使用的:

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

    DECLARE_METHODS();

    /*other public members*/

private:
    /*private members*/
};
class Class
{
public:
    Class();
    ~Class();

private:
    DECLARE_METHODS();

    /*private members*/
};
但人们知道,像这样使用会造成一些破坏:

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

    DECLARE_METHODS();

    /*other public members*/

private:
    /*private members*/
};
class Class
{
public:
    Class();
    ~Class();

private:
    DECLARE_METHODS();

    /*private members*/
};
…因为它偷偷地对它下面的所有内容声明了一个公共访问修饰符

它被使用了数千次,因此将最终的public:替换为private:将非常耗时,因为在适用的情况下,必须检查几乎所有的客户端才能移动宏或在宏之后打开public access修饰符。 删除所有修改器并取消bar()的保护不是一个选项

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

简短回答:否

原因:宏扩展完全由预处理器完成,在任何C++之前,都可以被解释为C++。 这意味着预处理器对代码视而不见——它可以是java、c、文本,甚至python(如果您没有对其进行注释的话),并且预处理器会乐于扩展宏

您想要做的事情可以通过奇怪的重复模板模式来实现


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

编辑:这实际上不起作用,收回

尚未选中此选项(我不使用
private
),但请尝试:


这(应该)避免更改后续成员的可见性说明符。

我会将其默认设置回
private
,然后修复中断的代码。实际上,我可能不会首先编写这样的宏,因为我怀疑是否有办法恢复原始说明符。也许包含所需声明的公共[虚拟]“接口”基类比宏更好。。。还有其他方法可以剥猫皮,但是选择最好的方法需要更多的领域信息。在这一点上,其中任何一项都可能是相当大的工作。但是我认为任何解决你当前情况的方法都需要一定的努力……虽然这在C语言中是有效的,但它并不是C++。至少在MSVC中你会得到一个语法错误。@StefanLundmark,奇怪。。。后来我检查过了(GCC;MSVC没有编译C++,也不超过G++编译C),它工作了,但是现在似乎没有了。在进一步的思考中,我想我必须有<代码>定义私有/*PISH **/<代码>,或者在我测试这个时候,它会产生这样的效果。