如何使用c++;没有名字的班级? 我在开源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; } #包括 使用名称空间std; #共同定义2(a,b)a##b #一起定义(a,b)一起定义2(a,b) #一起定义生成名称(a),\u计数器\u #定义生成生成名称(uu种子) 阶级基础{ }b; 类生成:公共基{ }产生; 类生成:公共基{ }产生; 类生成:公共基{ }产生; 类生成:公共基{ }产生; int main(){ 返回0; }

如何使用c++;没有名字的班级? 我在开源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; } #包括 使用名称空间std; #共同定义2(a,b)a##b #一起定义(a,b)一起定义2(a,b) #一起定义生成名称(a),\u计数器\u #定义生成生成名称(uu种子) 阶级基础{ }b; 类生成:公共基{ }产生; 类生成:公共基{ }产生; 类生成:公共基{ }产生; 类生成:公共基{ }产生; int main(){ 返回0; },c++,class,C++,Class,如我们所见,作者定义了几个类,这些类继承了一个基类。但是作者并不关心这些类的名称。所以我想知道在不指定名称的情况下如何使用这些类? 这是C++中的一种设计模式,我不知道吗?< /强> 谢谢:) 我想加上我的猜测来澄清这个问题 我猜: 这些类的名称是从_seed_u生成的,但是当我搜索文件时,我找不到对_seed_u的其他引用,因此我确信作者没有使用名称_seed_1、_seed_2来创建类。(事实上,作者在评论中说她不在乎班级名称) 我还猜测作者可能通过基类(虚拟函数)中定义的接口使用了

如我们所见,作者定义了几个类,这些类继承了一个基类。但是作者并不关心这些类的名称。所以我想知道在不指定名称的情况下如何使用这些类?

<强>这是C++中的一种设计模式,我不知道吗?< /强>

谢谢:)


我想加上我的猜测来澄清这个问题


我猜:

这些类的名称是从_seed_u生成的,但是当我搜索文件时,我找不到对_seed_u的其他引用,因此我确信作者没有使用名称_seed_1、_seed_2来创建类。(事实上,作者在评论中说她不在乎班级名称)

我还猜测作者可能通过基类(虚拟函数)中定义的接口使用了这些类。要做到这一点,作者仍然需要创建这些类,但正如我提到的,我在代码的其他部分中找不到_seed u,因此作者无法创建类,因此虚拟函数也无法工作

实际上,我尝试删除这些类定义,奇怪的是代码编译正确。然而,它失去了一些功能,但它不仅仅是核心转储。它仍然可以成功地完成一些任务

那么,有谁知道:

  • 我们如何使用这些类而不指定它们的名称
  • 这种设计是某种设计模式吗
  • 在哪种情况下,我们应该定义类而不考虑它们的名称
  • 正如我提到的,我删除了部分代码,并对其进行了编译。这怎么会发生?我的意思是,由于我从源代码中删除了许多类,那么如果代码的其他部分引用了这些类,那么源代码就无法编译。如果它编译了,我能不能断定这些类是不需要的
增加: 正如你们中的一些人所建议的, 完整的源代码在这里:。在文件./main/rewrite_const.cc中,作者使用宏ANON(lion 25)定义了许多类,而不关心它们的名称


非常感谢您的帮助:)

我建议您编辑代码并为类添加名称。这是一种奇怪的设计模式,我不建议您在任何事情上使用这种模式,除非您想阻止其他人使用您的类

如果作者希望您使用这些类,可能有某种方法可以使用它们,而无需编辑代码和添加名称。为此,您应该查阅文档

正如我提到的,我删除了部分代码,并对其进行了编译。这怎么会发生?我的意思是,由于我从源代码中删除了许多类,那么如果代码的其他部分引用了这些类,那么源代码就无法编译。如果它编译了,我能不能断定这些类是不需要的

所有生成的类都是从基类派生的。因此,如果删除一个类,那么它后面的所有类都会收到一个新生成的名称。如果代码现在已编译,则意味着其他代码只调用基类中的方法。但是另一个代码现在使用的类与它最初使用的不同,这会导致您观察到的错误

考虑这一点:

  • 最初生成的类具有名称A、B和C
  • 你取消了A级
  • 现在生成的类具有名称A和B。名为C的类不再存在,因此使用它的代码应该不再编译。以前使用类A和类B的代码,现在使用的是以前的类B和类C

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

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


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

这可能是为了阻止此库的用户自己实例化类,和/或使可执行文件的符号表混淆。应该有一些机制来获取实例(通过一些枚举或字符串)。如果它是开源的,你能分享到完整库的链接吗?这可能有助于弄清楚发生了什么。也许像这样生成类的原因是在每个类的静态初始化过程中做一些不同的事情(我认为注册同一类的单个对象或类工厂是一种相当常见的情况)。计数器甚至可以由构建脚本自动生成,该脚本使用不同的计数器值反复编译同一个文件,并每次指定不同的对象文件名。这个模式是在一些单元测试框架中发现的吗?显然“计数器”是一个micorosft预处理器扩展。嗨,Vee,我编辑了我的问题并添加了链接:)谢谢。你的回答为我提供了一个新的视角:)