尝试了解 RapidXml 内存分配

发布于 2024-10-11 16:29:48 字数 1978 浏览 6 评论 0原文

我在 C++ 程序中使用 RapidXml。好吧,没问题,它可以工作。我只是不明白为什么我必须使用指针而不是变量值...... 如果你看一下 RapidXml wiki 页面,会提供一些示例,这是 RapidXml 开发人员提供的示例:

#include <iostream>
#include <string>
#include "rapidxml-1.13/rapidxml.hpp"
#include "rapidxml-1.13/rapidxml_print.hpp"
int main(int argc, char** argv);
int main(int argc, char** argv) {
    using namespace rapidxml;
    xml_document<> doc;
    // xml declaration
    xml_node<>* decl = doc.allocate_node(node_declaration);
    decl->append_attribute(doc.allocate_attribute("version", "1.0"));
    decl->append_attribute(doc.allocate_attribute("encoding", "utf-8"));
    doc.append_node(decl);
    // root node
    xml_node<>* root = doc.allocate_node(node_element, "rootnode");
    root->append_attribute(doc.allocate_attribute("version", "1.0"));
    root->append_attribute(doc.allocate_attribute("type", "example"));
    doc.append_node(root);
    // child node
    xml_node<>* child = doc.allocate_node(node_element, "childnode");
    root->append_node(child);
    xml_node<>* child2 = doc.allocate_node(node_element, "childnode");
    root->append_node(child2);
    std::string xml_as_string;
    // watch for name collisions here, print() is a very common function name!
    print(std::back_inserter(xml_as_string), doc);
    std::cout << xml_as_string << std::endl;
    // xml_as_string now contains the XML in string form, indented
    // (in all its angle bracket glory)
    std::string xml_no_indent;
    // print_no_indenting is the only flag that print() knows about
    print(std::back_inserter(xml_no_indent), doc, print_no_indenting);
    // xml_no_indent now contains non-indented XML
    std::cout << xml_no_indent << std::endl;
}

那么,为什么它使用指向 xml_node 的指针???

我问这个是因为我需要一个函数来返回 xml_node...

所以如果我这样做:

xml_node<>* mynode = ... 返回*我的节点;

可以吗?因为我想稍后使用返回的节点及其所有子节点。 这样做好不好? 如果没有,我该怎么办?

I'm using RapidXml in a c++ program. Well ok no problem it works. I just do not understand why I must use pointers instead of variable values...
If you take a look to the RapidXml wiki page, some examples are provided, this is the one provided by RapidXml developers:

#include <iostream>
#include <string>
#include "rapidxml-1.13/rapidxml.hpp"
#include "rapidxml-1.13/rapidxml_print.hpp"
int main(int argc, char** argv);
int main(int argc, char** argv) {
    using namespace rapidxml;
    xml_document<> doc;
    // xml declaration
    xml_node<>* decl = doc.allocate_node(node_declaration);
    decl->append_attribute(doc.allocate_attribute("version", "1.0"));
    decl->append_attribute(doc.allocate_attribute("encoding", "utf-8"));
    doc.append_node(decl);
    // root node
    xml_node<>* root = doc.allocate_node(node_element, "rootnode");
    root->append_attribute(doc.allocate_attribute("version", "1.0"));
    root->append_attribute(doc.allocate_attribute("type", "example"));
    doc.append_node(root);
    // child node
    xml_node<>* child = doc.allocate_node(node_element, "childnode");
    root->append_node(child);
    xml_node<>* child2 = doc.allocate_node(node_element, "childnode");
    root->append_node(child2);
    std::string xml_as_string;
    // watch for name collisions here, print() is a very common function name!
    print(std::back_inserter(xml_as_string), doc);
    std::cout << xml_as_string << std::endl;
    // xml_as_string now contains the XML in string form, indented
    // (in all its angle bracket glory)
    std::string xml_no_indent;
    // print_no_indenting is the only flag that print() knows about
    print(std::back_inserter(xml_no_indent), doc, print_no_indenting);
    // xml_no_indent now contains non-indented XML
    std::cout << xml_no_indent << std::endl;
}

Well, why does it use a pointer to xml_node???

I ask this because I need to a function to return a xml_node...

So if I do this:

xml_node<>* mynode = ...
return *mynode;

is it ok?? Because I want to use the returned node and all its children later.
Is it good to do in this way?
If not, how should I do?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

昔梦 2024-10-18 16:29:50

那么,为什么它使用指向 xml_node 的指针

可能是因为返回指向节点的指针比返回时进行复制更快。

Well, why does it use a pointer to xml_node

probably because it's faster to return a pointer to the node than making a copy on return.

乖乖兔^ω^ 2024-10-18 16:29:50

好的...RapidXML 和许多其他类似 Xerces 的方法不返回值,而是返回指针,这样程序员就无法获取该值并一路进行复制...这样做是为了保留内存...

尤其是在谈论DOM,而且对于SAX来说几乎是一样的,这些解析器需要在程序运行的计算机RAM中创建非常复杂的内存分配结构。
为了提供性能等,所有构造函数和复制构造函数都是私有的。

看看图书馆......你会发现这个好技巧啊哈哈。

嗯,原因是我报告的以及大家建议我的。

我猜想,当使用 c、c++ 和低级语言时,编程的方式并不是那么直接……程序员不能很容易地获取一个节点并传递它或返回到函数和类。

OK... well RapidXML and many others like Xerces do not return values but pointers so that the programmer cannot take the value around and make copies all the way... this is done in order to preserve memory...

Especially when talkig about DOM, but also for SAX it is almost the same, these parsers need to create a very complex memory allocation structure in the computer's RAM where the program is run.
In order to provide performance and so on ALL CONSTRUCTORS and COPY-CONSTRUCTORS are PRIVATE.

Take a look at the library... you'll discover this nice trick ahah.

Well the reasons are the ones I reported and that everyone suggested me.

I guess that when using c, c++ and low level languages, it is not that immediate the way to program... a programmer cannot take a node and pass it or return to functions and classes very easily.

萌化 2024-10-18 16:29:49

返回指针可能是为了避免调用节点的复制构造函数。仅返回指针会更快,特别是考虑到节点可能已经在内部某处分配。

他们也可以返回一个引用,但他们可能希望保留在无效调用时返回 NULL 的能力。

如果您需要 xml_node,您始终可以取消引用该指针(首先检查 NULL)。不过,如果您确实想稍后使用返回的节点及其子节点,那么最好将返回的指针与 -> 一起使用。并按值传递指针。

Returning a pointer is probably done to avoid calling the copy constructor of the node. It is faster to just return a pointer, especially considering the node is probably already allocated somewhere internally.

They could have also returned a reference, but they might wish to retain the ability to return NULL on invalid calls.

If you need a xml_node, you could always dereference the pointer (check for NULL first). If you really want to use the returned node and its children later, though, it's probably best to just use the returned pointer with -> and pass the pointer around by value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文