我希望能够在代码中自动生成一个类。
我知道我可以打开一个可以打开的文本或脚本文件,并将该文件的内容加载到字符串矢量或字符串流中,然后从那里写回文件或文件集以生成类。我对解析方面的细节不感兴趣,这不是我真正想要的。
假设我有一个看起来像这样的文本文件:我上面的当前伪文件更长,详细解释更详细;但为简单起见,此处省略。如果您认为需要,请不要犹豫,我会发布。
脚本
// 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文件。由于它们被省略,我想在代码中生成这个类。
我不想诉诸使用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"
,然后在下面尝试使用该字符串声明该类时,它不会看到具有标识符名称的类的字符串和名称。然后,如果你之后尝试使用该类,它根本找不到类,而是找到名为name的字符串。是否可以使用某种已经内置的功能在此处附加所需的文本,以便在代码中自动生成类而无需键入它?我不确定如何从字符串中提取文本以将其用作类名称的标识符。
结论
阅读我相关问题中提供的评论和答案;然后它证明了我最初的假设,我没有提到它是真的。它无法完成。这确实需要从解析器的角度将类写入其各自的文件。
对不起,但这不是C ++的工作原理。编译器理解关键字class
和成员名称之类的东西,并且通常将所有理解用于将所有这些理解转换为机器代码,机器代码通常仅使用大量原始指针和偏移量,而不是成员或类似的东西的名称。 。只有在编译器完成后,才能运行程序,并且典型程序本身并不包含任何能够理解类,成员名称或赋值运算符等内容的功能。
那你有什么选择?您可以编写一些能够执行常规类所做的事情的实用程序,但是您将无法以与编译器从程序中的头文件中学习的类相同的方式引用它。这看起来像是这样的:
{
CustomClass myclass( "Foo.cls" );
CustomObject obj = myclass.create(); // default constructor
CustomObject obj_copy = obj; // copy constructor
}
或者您可以在运行时执行编译和加载插件的操作,但尝试这样做有一些复杂性。这仍然不允许你使用自定义类,如编译到你的程序中,但它允许任意C ++代码(这既强大又危险,因为有人可能会意外或恶意地破坏任何方式)。这将涉及将您的配置文件转换为您编写的实际临时C ++源文件,使用特殊选项运行编译器以创建“共享库”(Unix,包括Linux)或“DLL”(Windows),然后使用该文件加载该库dlopen
(许多Unix风格,包括Linux)或LoadLibrary
(Windows)。对于编译步骤,这意味着您运行程序的任何计算机都需要安装编译器,并且它应该是您用于编译程序的编译器版本的一个相当接近的版本。如果此编译器位于特殊路径上,您的程序将如何被告知该路径?
另外,您需要设计一个插件架构,考虑如下: