【问题标题】:Creating a C++ Class from a textfile/XML file从文本文件/XML 文件创建 C++ 类
【发布时间】:2012-11-28 17:46:00
【问题描述】:

我基本上想为我想要制作的一些数据类型创建一个内部结构。这些数据类型将保存我程序中的大部分信息(基本上是一个大型数据库,但我想避免设置一个使用的麻烦)并将被序列化/反序列化。

但我想从文本文件/ml 文件的布局中即时创建这些类/结构。例如:

container Music
field string name
field largenumber filesize
end container

这是一个非常基本的例子:在上面,'container' 是数据类型(类或结构),'field' 表示一个变量(字符串是.. 一个 stl 字符串,一个大数字是一个无符号整数或类似的东西。是的,我意识到我想要一个检查正确语法的 C++ 解析器(作为编译器)之类的东西。

我基本上希望我的程序的用户创建自己的数据类型(添加字段/删除字段/创建自己的结构),然后将其永久保留在我的程序中。

(我已经弄清楚了如何在执行此操作时进行序列化/反序列化 - 我所要做的就是确保我还将最后创建的类/结构文本文件与序列化数据一起保存,这样我就可以重新创建数据类型当我反序列化时)。

有谁知道如何去做,或者建议更好地实现我的设计?

附:显然,这些信息需要在运行时而不是编译时创建。

【问题讨论】:

  • 你能说得清楚一点吗?例如,您是否无法将这些数据视为一个类?也就是说,你能写出一个可以包含可变数量的可变类型元素的类吗?还是在那之后你的问题是序列化它?或者你一般会问是否有更好的解决方案?
  • 你的附言一点也不明显。您将如何在运行时编译生成的 C++ 代码?
  • 您不能在运行时在 C++ 程序中创建新类型。您需要为您的用户创建一种语言来表达他们的类型(或重用现有语言),并在您的程序中实现它。这种语言不必类似于 C++。这里有两个不同的问题,(1)使用什么样的语言和(2)如何实现它。不,做三个。 (3) 你真的不需要 DBMS 吗?
  • 当您说“然后将其永久保留在我的程序中”时,我假设您的意思是定义方面,而不是生成可编译代码并将其扔到您的地址空间中。我看到后者是用 Java 完成的(一个规则引擎,老实说是一个奇迹),但在 C++ 中,我认为字典和合适的变体数据类型是你能做的最基本的事情。
  • 好吧,澄清一下——假设你有一个很好的图形界面,它有行和列。每一行将代表一个完整的“条目”,每一列将是一个“变量”——整个页面将是数据库中的一个表。假设您想添加另一列(数据结构中的新变量)。您还希望在程序关闭时将该列保留在输出数据中。那么 DBMS 会更容易使用吗?

标签: c++ class parsing struct text-files


【解决方案1】:

对于 XML 到对象的转换,您实际看到的是 SOAP 的一部分。我更喜欢 RapidXML,但您可以尝试其他 XML 解析器来创建/读取您的对象。

对于文本文件,您可能必须编写自己的解析器来正确处理文本文件并期望正确的类型和定义,然后相应地生成对象。

我同意,除非存在通用接口,否则动态创建对象并为其填充值并非易事。

作为旁注,既然您说您希望您的用户动态地“创建”类型,为什么不研究一种简单的脚本语言(或自己制作一个 DSL?)

【讨论】:

  • 如果上述选项不起作用,我将对此进行调查。谢谢你的回复!
【解决方案2】:

正如您所建议的,我会通过编写一个 XML 解析器来做到这一点,并且数据类型定义将在文件中。这样,解析变得非常容易(使用任何 XML 读取库)。您在运行时创建数据类型,您所需要的只是:一个类 Container 和一个类 Field,您可以在其中存储名称、类型等。

您预处理您的 XML 文件,生成一个填充您的某些数据结构的函数,通常如下所示:

Field newfield1 (name, type, whatever);
Field newfield2 (name2, type2, whatever2);
...
Container newContainer;
newContainer.addField(newfield1);
newContainer.addField(newfield2);
...

当然,您可以比这更好地组织您的代码,但这只是给出一个想法。首先将您的数据类型写为 XML,预处理您的 XML 并生成“运行时”.cpp 文件以创建您的动态类型,将其包含在您的项目中,然后您可以根据需要使用您的类型。

要创建不同类型的字段(事先不知道),您可以使用 boost::variant(也可以从 XML 生成类型列表)。您甚至可以为每个字段生成一个 typedef,以确保稍后在您使用 boost:get 时使用正确的类型。

【讨论】:

  • 太棒了!是的,这听起来和我想做的完全一样——这个概念看起来也像是编译器解析它的信息的方式。非常感谢!
  • 阅读后,我发现了 boost::any 类 - 可能,我可以有一个 boost::any 变量的映射,是吗?只要用户指定数据类型是什么(从一系列预定义类型中),就可以很容易地从文件中读取 XML 格式的数据并将其转换为正确的类型。与此方法相比,我不确定使用变体将如何工作。你能解释一下吗?
  • 是的,当然,boost::any 也可以,这取决于你如何使用它。我更喜欢 boost::variant,因为它提供静态检查而不是运行时检查,但这是个人喜好问题。看看这个页面Boost comparison page 来决定什么最适合你。
  • 如果你没问题,请注意作为关闭线程的答案。
  • 啊哈,我的意思是:点击我帖子旁边的“打勾”,这样帖子就可以标记为“已解决”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-03
  • 2012-02-28
  • 2017-03-06
相关资源
最近更新 更多