如何在 c++ 中创建一个可调试的文件作用域(静态?)类

How to make a debuggable file scoped (static?) class in c++?

本文关键字:文件 调试 作用域 静态 一个 创建 c++      更新时间:2023-10-16

我在 cpp 文件中定义了很多类。通常使用缺乏想象力的名称,例如"实施"。并且担心名称冲突,因为这些很难调试(假设编译器静默地删除其中一个定义)。但是,我也希望能够调试我的程序,因此匿名命名空间不是一个选项。那么,是否可以在不使用命名空间的情况下在 c++ 中定义文件范围(又名翻译单元范围)类?如果是,如何?

c
中的文件范围在 c 中,可以使用 int foo; 创建一个全局变量,并使用 static int foo; 将变量限制在文件范围内。同样,文件范围的函数也是使用 static 关键字创建的,例如 static void bar(); 。结构不定义数据或可执行代码,因此实际上始终是文件范围的。

虚拟成员函数
现在 c++ 引入了虚拟成员函数,这导致结构(又名类)包含数据和可执行代码。因此,结构现在是全局定义的。但是,不允许使用静态使结构再次具有文件范围。即 static struct Foo{};不编译。

命名空间
为了解决名称冲突问题,c++ 还引入了命名命名空间。这些也可用于包装结构,使其成为伪文件范围。尽管这仍然迫使您为每个文件选择一个唯一的名称(您甚至不关心)。作为解决方案,他们还引入了匿名命名空间。不幸的是,gdb 和 Visual Studio 调试器似乎都不支持匿名命名空间(基本上不可能引用匿名命名空间中的任何内容)。

部分解决方案是使用匿名结构/类并对这些结构/类进行 typedef,因为两者都是文件范围的(C - 限制结构作用域),除了不可能显式定义构造函数或析构函数(无命名结构的构造函数)。下面的示例使用 gcc 编译并运行良好,还允许 gdb 在 method() 上放置断点:

接口.h

struct Iface {
  virtual void method()=0;
};

implementation_a.cppimplementation_b.cpp

#include "interface.h"
typedef struct : Interface {
  virtual void method();
} Implementation;
void Implementation::method() {
  // Do stuff...
}
Interface * new_implementation_a() { // or new_implementation_b
  return new Implementation();
}

主.cpp

#include "iface.h"
int main() {
  Interface * a = new_implementation_a();
  Interface * b = new_implementation_b();
  a->method();
  b->method();
  return 0;
}