如何使用没有名称的c ++类?

时间:2016-11-28 11:54:35

标签: c++ class

我在开源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)来定义许多类而不关心它们的名称。

非常感谢您的帮助:)

2 个答案:

答案 0 :(得分:4)

我建议您编辑代码并添加类的名称。这是一种奇怪的设计模式,我建议你不要使用这种模式,除非你想阻止别人使用你的类。

如果作者希望您使用这些类,可能有一些方法可以在不编辑代码和添加名称的情况下使用它们。您应该参考相关文档。

  

正如我所提到的,我删除了部分代码,并编译了它。怎么会发生这种情况?我的意思是,因为我从源代码中删除了许多类,所以如果代码的其他部分引用这些类,则源无法编译。如果它编译,我可以断定不需要那些类吗?

所有生成的类都是从基类派生的。因此,如果删除一个类,则它之后的所有类都会收到一个新生成的名称。如果代码现在编译,则意味着其他代码仅调用属于基类的方法。但是其他代码现在使用的是其他类以外的类,这会导致您观察到的错误。

考虑一下:

  • 最初生成的类具有名称A,B和C.
  • 您删除了A类。
  • 现在生成的类具有名称A和B.名为C的类不再存在,因此使用它的代码不再编译。而之前使用过A类和B类的代码,它现在使用的是以前的B和C类。

答案 1 :(得分:3)

这些类确实有名称。只有这些名称不会向人类读者显示,并且在预处理器运行之前未指定。 (如果使用选项-E运行编译器,它将只运行预处理器阶段并在编译器正确看到它时输出代码,包括类名。)

AFAIK,没有明智的理由以这种方式隐藏名字。如果作者不希望人类编写使用这些类的代码,那么还有其他方法。

在用户要包含的头文件中定义这样的名称意味着除了通过多态之外,它们不能在库中使用(因为库不能知道它们的名称)。这就是为什么删除它们对编译没有区别的原因。