我在开源c ++代码中遇到了问题。以下是描述我的问题的小型简化版本:
#include <iostream>
using namespace std;
#define TOGETHER2(a,b) a ## b
#define TOGETHER(a,b) TOGETHER2(a,b)
#define GENERATE_NAME(a) TOGETHER(a,__COUNTER__)
#define GENERATE GENERATE_NAME(__seed_)
class base{
}b;
class GENERATE:public base{
}GENERATE;
class GENERATE:public base{
}GENERATE;
class GENERATE:public base{
}GENERATE;
class GENERATE:public base{
}GENERATE;
int main(){
return 0;
}
正如我们所看到的,作者定义了几个继承基类的类。但作者并不关心课程的名称。所以我想知道如何在不指定名称的情况下使用这些类?
这是一种我不知道的c ++设计模式吗?
谢谢:)
我想加上我的猜测,以明确问题。
我的猜测:
这些类的名称是从__seed_生成的,但是当我搜索文件时,我找不到对__seed_的其他引用,所以我确信作者没有使用名称__seed_1,__ seed_2来创建类。 (实际上作者说评论她并不关心课程的名称)
我还猜测作者可能已经通过基类(虚函数)中定义的接口使用了这些类。为此,作者仍然需要创建这些类,但正如我所提到的,我在代码的其他部分找不到__seed_,因此作者无法创建类,因此虚函数也不起作用。
实际上,我尝试删除这些类定义,奇怪的是代码编译正确。然而,它失去了一些功能,但它不仅仅是核心转储。它仍然可以成功完成某些任务 u
所以,有人知道:
增加: 正如你们有些人推荐的那样 完整的源代码在这里:MIT Cryptdb。在文件./main/rewrite_const.cc中,作者使用宏ANON(狮子座25)来定义许多类而不关心它们的名称。
非常感谢您的帮助:)
答案 0 :(得分:4)
我建议您编辑代码并添加类的名称。这是一种奇怪的设计模式,我建议你不要使用这种模式,除非你想阻止别人使用你的类。
如果作者希望您使用这些类,可能有一些方法可以在不编辑代码和添加名称的情况下使用它们。您应该参考相关文档。
正如我所提到的,我删除了部分代码,并编译了它。怎么会发生这种情况?我的意思是,因为我从源代码中删除了许多类,所以如果代码的其他部分引用这些类,则源无法编译。如果它编译,我可以断定不需要那些类吗?
所有生成的类都是从基类派生的。因此,如果删除一个类,则它之后的所有类都会收到一个新生成的名称。如果代码现在编译,则意味着其他代码仅调用属于基类的方法。但是其他代码现在使用的是其他类以外的类,这会导致您观察到的错误。
考虑一下:
答案 1 :(得分:3)
这些类确实有名称。只有这些名称不会向人类读者显示,并且在预处理器运行之前未指定。 (如果使用选项-E
运行编译器,它将只运行预处理器阶段并在编译器正确看到它时输出代码,包括类名。)
AFAIK,没有明智的理由以这种方式隐藏名字。如果作者不希望人类编写使用这些类的代码,那么还有其他方法。
在用户要包含的头文件中定义这样的名称意味着除了通过多态之外,它们不能在库中使用(因为库不能知道它们的名称)。这就是为什么删除它们对编译没有区别的原因。