来自文本字符串或其他机制的代码 class 自动生成器

An in code class auto generator from a string of text or some other mechanism

如果可能的话,我希望能够在代码中自动生成 class。

我知道我可以打开一个文本或脚本文件,然后将该文件的内容加载到字符串向量或字符串流中,然后从那里写回一个文件或一组文件生成 class。我对解析方面的细节不感兴趣,这不是我真正想要的。

假设我有一个看起来像这样的文本文件: 我当前上面的伪文件更长,有更详细的解释;但为简单起见,此处省略。如果你觉得需要它,请不要犹豫,我会post它。

脚本

// The finalized scripting file & its parser will not have any comments within code sections.
// Comments can be found before & after the <begin:file> & <end:file> sections

// This is the beginning of the file and whether or not a header and or cpp file
// is generated or not. If not then the idea is to generate the class in code directly.
// <begin:file "Foo.h"> // header only otherwise 
// <being:file "Foo.h", "Foo.cpp"> for both header and cpp 

<begin:file> 
<class:"Foo">
<private:>
  <variables: int=mX,mY,mZ float=mWidth,mHeight>
<public:>
  <constructor:defualt=t, init=t>
  <constructor:copy=t> // automatically generates both copy() & operator=() as = default;
  <constructor:copy=f> // declares both copy() & operator() as = delete;
  <destructor:default=t>
<end:class>
<end:file>

在上面的脚本中我有 <begin:file> 因为它后面没有字符串;这意味着我不想写入文件来创建头文件和/或 cpp 文件。由于它们被省略,我想在代码中生成这个 class。

我不想求助于 macros。如果可能的话,我可以使用模板或其他一些机制。

我不确定的是:假设我在 <class:"Foo"> 中阅读的部分,这将告诉我的解析器我想要一个 class 命名为 Foo 这就是 shell:

class Foo {}; 

正如预期的那样,但是我们还不能写结尾的 }; 部分,因为我们还没有到达 <end:class> 部分。所以在这一点上我们需要写出 class Foo { 而我在这里看到的部分或问题是我不知道如何能够获取 std::string name("Foo"); 之类的文本或字符串 并将其附加在 c++ 关键字 class 之后。伪例子:

{
     std::string name("Foo");

     class name {
     public:
         int x; 
     };

     std::cout << name << std::endl; // compiles and prints to the console "Foo"
     std::cout << name.y << std::end; // will not compile.
}

这里的问题是在 c++ 的关键字 class 之后需要一个标识符,而编译器不会接受这个。编译器将声明一个名为 name 的字符串,其中包含 "Foo" 的内容,然后在下面尝试使用该字符串声明 class 时,它看不到字符串和名称class 与标识符名称。然后,如果您随后尝试使用 class,它根本找不到 class,而是找到名为 name 的字符串。是否可以使用某种已经内置的功能在此处附加所需的文本以在代码中自动生成 class 而无需输入?我不确定如何从字符串中提取文本以将其用作 class 名称的标识符。


结论

阅读我的相关问题中提供的评论和答案;然后它证明了我最初没有提到的假设是真实的。这是不可能的。从解析器的角度来看,这确实需要将 class 写入它们各自的文件。

抱歉,这不是 C++ 的工作方式。编译器理解关键字 class 和成员名称之类的东西,并且通常将所有理解用于将所有这些转换为机器代码,机器代码通常只使用大量原始指针和偏移量,而不是成员名称或类似的事情。只有在编译器完成后,您才能 运行 您的程序,而典型的程序本身并不包含任何理解诸如 classes、成员名称或赋值运算符之类的东西的能力。

那么你有什么选择呢?您可以编写一些实用程序,这些实用程序能够完成一般 class 会做的一些事情,但您将无法以与编译器了解的 class 相同的方式引用它来自程序中的头文件。这可能看起来像:

{
    CustomClass myclass( "Foo.cls" );
    CustomObject obj = myclass.create(); // default constructor
    CustomObject obj_copy = obj; // copy constructor
}

或者您可以在 运行 时做一些编译和加载插件的事情,尽管尝试这样做会有些复杂。这仍然不允许您像编译到您的程序中那样使用自定义 class,但它允许任意 C++ 代码(这既强大又危险,因为有人可能会意外或恶意破坏任何东西)。这将涉及将您的配置文件转换为您写出的实际临时 C++ 源文件,运行使用特殊选项编译编译器以创建 "shared library"(Unix,包括 Linux)或 "DLL" (Windows),然后使用 dlopen(许多 Unix 风格,包括 Linux)或 LoadLibrary (Windows) 加载该库。对于编译步骤,这意味着您 运行 您的程序需要安装编译器的任何计算机,它应该是与您用于编译程序的编译器版本相当接近的版本。如果这个编译器在一个特殊的路径上,你的程序将如何被告知那个路径?

此外,您需要设计一个插件架构,考虑以下事项:

  • 插件如何与程序交互?它是否提供仅输入和输出字符串向量的函数?它是否提供了创建从某些抽象基础 class 派生的 class 对象的函数?

  • 如果插件需要使用任何基础 classes 或特定于您的程序的专用函数,您将如何确保在编译插件时向编译器提供所需的头文件?