Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sql-server-2005/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 实现复制构造函数_C++_Copy Constructor - Fatal编程技术网

C++ 实现复制构造函数

C++ 实现复制构造函数,c++,copy-constructor,C++,Copy Constructor,我有下面的类定义,它需要一个复制构造函数,所以需要进行深度复制来复制原始指针。有人能给我们建议如何最好地做到这一点吗 使用XML 谁对投票不满而没有给出理由?编写副本构造函数总是要为每个成员变量做“正确的事情”。如果没有看到你的dom实现的API文档等,这里很难说什么是“正确的事情”。也许它们有一个复制构造函数,或者一个制作深度复制的函数。也许您不需要语义上的深度副本(例如,对于dominemplementation) 一句话,很难说没有看到API文档你肯定有躺在周围 编辑:那么您正在使用Xer

我有下面的类定义,它需要一个复制构造函数,所以需要进行深度复制来复制原始指针。有人能给我们建议如何最好地做到这一点吗

使用XML


谁对投票不满而没有给出理由?

编写副本构造函数总是要为每个成员变量做“正确的事情”。如果没有看到你的
dom实现的API文档
等,这里很难说什么是“正确的事情”。也许它们有一个复制构造函数,或者一个制作深度复制的函数。也许您不需要语义上的深度副本(例如,对于
dominemplementation

一句话,很难说没有看到API文档你肯定有躺在周围

编辑:那么您正在使用Xerces-C。您以前没有告诉我们

编辑2:让我们看看,然后

据我所见,Xerces-CAPI确实没有提供任何复制文档对象的“简单”方法。在AICT中,您必须创建一个全新的文档(
impl->createDocument()
),然后手动复制任何属性和子节点


这非常尴尬,我会提出这样一个问题:“无论如何,我为什么要复制我的
XMLDocument
对象?它在语义层面上有意义吗?”。(个人经验:如果在使用一个使用良好的API时事情变得不好,那么很可能是你做错了什么,因为有一个简单的方法可以解决问题。XML不是我的强项,所以我在这里没有深度。)

Devsolar关于拷贝构造函数的观点是正确的。听从他的劝告

此外,您真的不应该复制DOM结构。使用XML时的标准过程是编写一个处理程序,从DOM/SAX获取数据,并基于该结构构建本机对象。读取完所有应该在内存中构建的DOM/SAX元素后:

  • 一种数据结构,用于保存XML中所需的所有数据
  • 从XML构建但与XML分离的对象。您可以在应用程序中使用此对象。很可能将来会将此对象序列化为xml

  • 这样您就不需要复制DOM。而是构建本机对象来表示数据。请记住,您希望将应用程序与XML分离。如果将来您决定使用二进制序列化呢

    如果您所使用的库可以实现您想要的深度复制,那么实现这一点的方法就是确保类中所有的数据成员都知道如何复制自己(使用自己的复制构造函数)。对于每个数据成员的类型,依次类推。在实践中,这意味着从头定义可复制的包装类型

    注意准确定义什么是拥有的(要复制)什么不是(存在于其他地方,只是引用)

    这种分层包装的主要原因是,当某个部件的复制失败时,您希望C++自动销毁。但它也大大简化了事情。当你了解到组成部分的最低层次时,你可能会得到关于复制这样一个最小部分的更好的建议


    干杯,

    这一页肯定会有帮助:


    请注意,编写复制构造函数和赋值运算符之间存在差异,但本文也讨论了这一点。

    我建议重新考虑一下所有权规则。如果你想做一个深度复制,很可能你正在试图解决哪个变量拥有其他变量的内存。在您的例子中,似乎您关心拥有v_节点和DOM相关变量的每个XMLDocument实例

    解决潜在问题的另一种方法是将实例变量包装在智能指针中

    这样,每次复制construct XMLDocument时,都会增加每个IVAR上的ref计数。每次调用XMLDocument实例的dtor时,ref计数都会递减。本质上,您将每个XMLDocument实例的生存期与其IVAR分离。相反,拥有它的是ref count


    我不是xerces方面的专家,但值得一试各种智能ptr实现,例如boost库。

    这些类没有复制构造函数。@DevSolar:传递这个XMLDocument对象并按值从函数返回它怎么样?我是否应该始终返回指针?还是一个聪明人?@托尼:我真的不明白你在这里想干什么。Xerces-CAPI的包装器?Xerces-C通过指针处理
    DOMDocument
    对象,不允许(轻松)复制
    DOMDocument
    s。除非你有什么特别的想法(以及完成它的技巧),否则你应该注意这一点,而不是试图“强迫”它做出不同的行为。@DevSolar,我只是想将整个程序中需要的标准XML操作的复杂性封装在一个类中,并且只使用xerces中我需要的位。然后我的包装器可以在程序的其余部分中使用,如果有人决定更改要使用的XML库,整个程序都没有受到影响。您可能应该在问题中提到,您使用的是这个类,而不是您自己的类:这些类是否有某种形式的clone()接口?如果不是,如果你想复制对象层次结构(意味着你必须手动完成,要么自己遍历节点,要么以某种方式序列化和反序列化文档),我看不到任何克隆,那么SOL是什么意思呢?需要注意的是,我使用它已经有几年了。。。当心Xerces的内存泄漏,并非常小心如何使用它的内存。我怀疑丢失的复制构造函数与内存泄漏有关。抱歉,删除了复制构造函数注释。。。这并不总是正确的事情,我想不会
    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 &currentnode);
    
      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
    
     };
    
    document = impl->createDocument(0, "mydoc", 0);