реализация конструктора копирования - PullRequest
4 голосов
/ 03 ноября 2010

У меня есть следующее определение класса, и ему нужен конструктор копирования, поэтому создаются глубокие копии для копирования необработанных указателей. Кто-нибудь может посоветовать, как лучше всего это сделать?

Использование 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 &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

 };

DOMDocument создается с вызовом функции и , поэтому является элементом DOME. Так что я не могу просто назвать новые на этих указателях.

Не уверен, что я буквально воссоздаю все эти объекты?

Пример:

document = impl->createDocument(0, "mydoc", 0);

Кто впал в ярость и не получил причину ???

Ответы [ 5 ]

2 голосов
/ 10 ноября 2010

Эта страница, безусловно, может помочь:
http://icu -project.org / документы / документы / cpp_report / the_anatomy_of_the_assignment_operator.html

Обратите внимание, что они отличаются от написания конструктора копирования и оператора присваивания, но этот момент также обсуждается в статье.

2 голосов
/ 03 ноября 2010

При написании конструктора копирования всегда нужно делать «правильные вещи» для каждой переменной-члена. Не видя документации по API для ваших DOMImplementation и т. Д., Трудно сказать, что было бы здесь "Правильным". Возможно, для них есть конструктор копирования или функция для создания глубокой копии. Возможно, вам не требуется глубокая копия, семантически (например, для DOMImplementation).

Итог, трудно сказать, не видя документацию по API, которая у вас наверняка есть ...

Редактировать: Итак, вы используете Xerces-C. Ты не говорил нам этого раньше ...

Редактировать 2: Посмотрим, тогда ...

API Xerces-C действительно не предоставляет какие-либо "легкие" средства копирования объекта документа, из того, что я вижу. AFAICT, вам придется создать совершенно новый документ (impl->createDocument()), а затем вручную скопировать любые атрибуты и дочерние узлы.

Это так неловко, я бы поднял вопрос ", почему я все равно хочу скопировать мой XMLDocument объект? Имеет ли это вообще смысл на семантическом уровне?". (Личный опыт: если во время работы с хорошо используемым API дела идут плохо, есть вероятность, что вы делаете что-то не так, иначе был бы легкий путь. XML - не моя сильная сторона, поэтому я не в себе здесь.)

1 голос
/ 03 ноября 2010

Если необходимое глубокое копирование возможно с используемой вами библиотекой, то для этого нужно убедиться, что каждый владеющий *1002* член данных вашего класса XMLDocument знает, каккопировать себя (используя собственный конструктор копирования).И так далее рекурсивно для каждого типа элемента данных.На практике это означает определение копируемых типов оболочек с нуля.

Позаботьтесь о том, чтобы точно определить, что принадлежит (будет скопировано), а что нет (существует в другом месте и только что на него ссылаются).

ОсновнойПричиной такого иерархического переноса является то, что вы хотите, чтобы автоматическое уничтожение C ++ срабатывало при сбое копирования части.Но это также значительно упрощает вещи.А когда вы переходите к самым низким уровням составных частей, вы можете получить лучший совет по копированию такой самой маленькой части.

Cheers & hth.,

1 голос
/ 03 ноября 2010

Devsolar прав насчет конструкторов копирования.Прислушайтесь к его совету.

Более того, вам не следует копировать структуры DOM.Стандартной процедурой, когда я работаю с XML, является написание обработчика, который получает данные из DOM / SAX и создает собственный объект на основе этой структуры.Как только вы закончите читать все элементы DOM / SAX, вы должны сконструировать их в памяти:

  1. Структура данных, которая содержит все необходимые вам данные из XML.построен из XML, но отделен от XML.Вы используете этот объект в вашем приложении.Скорее всего, вы будете сериализовать этот объект в xml в будущем.

Таким образом вам не нужно копировать DOM.Вместо этого вы создаете собственные объекты для представления данных.Помните, что вы хотите отделить свое приложение от XML.Что если в будущем вы решите использовать двоичную сериализацию?

0 голосов
/ 17 ноября 2010

Я бы рекомендовал немного переосмыслить правила владения. Если вы хотите сделать глубокое копирование, скорее всего, вы пытаетесь обойти то, какая переменная владеет памятью других переменных. В вашем случае кажется, что вы заботитесь о каждом экземпляре XMLDocument, владеющем переменными v_nodes и DOM.

Еще один способ решения основных проблем - обернуть переменные вашего экземпляра в интеллектуальные указатели.

Таким образом, каждый раз, когда вы копируете конструкцию XMLDocument, вы просто увеличиваете счетчик ссылок для каждой из иваров. Каждый раз, когда вызывается dtor для экземпляра XMLDocument, количество ссылок уменьшается. По сути, вы отделяете время жизни каждого экземпляра XMLDocument от его ivars. Вместо этого ему принадлежит счетчик ссылок.

Я не эксперт по xerces, но стоит проверить различные реализации smart ptr, например библиотека повышения.

...