我有以下类定义,它需要一个复制构造函数,因此可以复制原始指针。有人可以建议如何做到最好吗?
将xerces-c++用于XML
class XMLDocument
{
private:
typedef std::vector<XML::XMLNode> v_nodes;
public:
XMLDocument::XMLDocument();
XMLDocument::XMLDocument(const XMLDocument& copy);
XMLDocument::~XMLDocument();
XMLDocument& operator=(XMLDocument const& rhs);
void CreateDocument(const std::string& docname);
void AddChildNode(XMLNode& node);
void RemoveNode(XMLNode& node);
void AddNodeValue(XMLNode& node, const std::string& value);
void AddNodeValue(XMLNode& node, int value);
void AddNodeValue(XMLNode& node, double value);
void AddNodeValue(XMLNode& node, float value);
std::string GetXMLAttributes();
std::string GetXMLAttribute(const std::string& attrib);
std::string GetXMLNodeText(XML::XMLNode& node);
std::string DumpToString();
XMLNode GetXPathNode(const std::string xpathXpression);
XMLNode GetNode(const XMLNode ¤tnode);
typedef v_nodes::iterator nodes_iterator;
nodes_iterator begin()
{
nodes_iterator iter;
iter = xmlnodes.begin();
return iter;
}
nodes_iterator end()
{
nodes_iterator iter;
iter = xmlnodes.end();
return iter;
}
private:
v_nodes xmlnodes;
bool InitializeXML();
DOMImplementation* impl; //Abstract
DOMDocument* document; //Abstract
DOMElement* rootelement; //Abstract
};
DOMDocument 创建时调用函数,所以是DOMElement。所以我不能只是在这些指针上调用new。
不确定我是否只是重新创建所有这些对象?
示例:
document = impl->createDocument(0, "mydoc", 0);
谁进行了一次沮丧的愤怒并没有给出理由?
答案 0 :(得分:2)
编写复制构造函数总是为每个成员变量做“正确的事”。如果没有看到DOMImplementation
等的API文档,很难说“正确的事情”会是什么。也许它们有一个复制构造函数,或者是一个进行深层复制的函数。也许你不是需要一个深层拷贝,在语义上(例如DOMImplementation
)。
最重要的是,如果没有看到API文档就很难说你肯定已经躺在那里了......
编辑:所以你使用的是Xerces-C。你之前没有告诉我们......
编辑2:让我们看看,然后......
Xerces-C API确实不提供任何“简单”的复制文档对象的方法,从我所看到的。 AFAICT,您必须创建一个全新的文档(impl->createDocument()
),然后手动复制任何属性和子节点。
这是如此尴尬,我会提出一个问题“为什么我是否想要复制我的XMLDocument
对象?无论如何它在语义层面上是否有意义?”。 (个人经验:如果在使用一个使用良好的API时情况变得很难看,你可能会做错事,因为否则会有一个简单的方法.XML不是我的强势,所以我不在我的深度此处。)
答案 1 :(得分:2)
此页面可能会有所帮助:
http://icu-project.org/docs/papers/cpp_report/the_anatomy_of_the_assignment_operator.html
请注意,编写复制构造函数和赋值运算符之间存在差异,但本文也讨论了这一点。
答案 2 :(得分:1)
Devsolar对于复制构造函数是正确的。听取他的意见。
此外,你真的不应该复制DOM结构。使用XML时的标准过程是编写一个从DOM / SAX获取数据的处理程序,并根据该结构构建一个本机对象。一旦你完成了你应该在内存中构建的所有DOM / SAX元素:
这样您就不需要复制DOM了。您可以构建本机对象来表示数据。请记住,您希望将应用程序与XML分离。如果您将来决定使用二进制序列化怎么办?
答案 3 :(得分:1)
如果您正在使用的库可以进行深层复制,那么实现它的方法是确保您的班级XMLDocument
中的每个拥有的数据成员知道如何复制自己(使用自己的复制构造函数)。等等每个数据成员的类型递归。实际上,这意味着从头开始定义可复制的包装类型。
注意确切地定义所拥有的(被复制的)和不属于的(在其他地方存在并且仅被引用)。
这种分层包装的主要原因是,当某个部件的复制失败时,您希望C ++的自动销毁。但它也大大简化了事情。当你得到最低级别的组成部分时,你可能会得到更好的建议来复制这么小的部分。
干杯&amp;第h。,
答案 4 :(得分:0)
我建议稍微重新考虑所有权规则。如果你想做一个深层复制,你可能正在尝试解决变量拥有其他变量的内存。在您的情况下,您似乎关心拥有v_nodes和DOM相关变量的XMLDocument的每个实例。
解决潜在问题的另一种方法是将实例变量包装在智能指针中。
通过这种方式,每次复制构造XMLDocument时,您只是在每个ivar上碰撞引用计数。每次调用XMLDocument实例的dtor时,ref计数都会减少。实质上,您将每个XMLDocument实例的生命周期与其ivars分离。相反,它是拥有它的引用计数。
我不是xerces的专家,但值得查看各种智能ptr实现,例如:升级库。