2014-09-01 4 views
0

Я возвращаюсь в C++ после перерыва в течение десятилетия и обнаружил, что многое происходит, когда меня нет, и я думаю, что мне не хватает чего-то фундаментального в современном рамки.Перегрузка возвращаемого класса (например, документ DomParser's в xmlpp)

У меня есть документ. Это мой документ. Это xml-документ, но с дополнительными функциями, поэтому с точки зрения дизайна он должен быть получен из xmlpp :: Document.

Однако он загружается из источника, что означает переход через xmlpp :: DomParser, который возвращает базовый объект xmlpp :: Document - не то, что я хочу.

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

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

Спасибо.

ответ

0

Вы можете создать декоратор или просто перегрузить копии (и переместить, если c++11) операторы присваивания и конструкторы, поэтому ваш объект будет создан из xmlpp::Document, который вы получите в качестве подкласса этого типа.

+0

Спасибо, но еще раз, это копирование результатов.В этом конкретном случае я, вероятно, сделаю это и подумаю о документе парсера как фрагменте документа (последующие фрагменты должны быть обработаны и объединены в любом случае), но я все время вижу проблески более элегантного решения. Возможно, мне нужно проанализировать источник GtkBuilder :: get_widget_derived. Я пытаюсь правильно изучить структуру и не стать одним из тех разработчиков, которые принимают новую концепцию, полностью упускают из виду и пытаются заставить ее вести себя так, как они привыкли. – Mike

+1

AFAIK, это лучший способ сделать это. С C++ 11 вы можете оптимизировать это с помощью семантики перемещения, а для предыдущей версии RVO удаляет эту копию. Ваш объект создается из 'xmlpp :: Document', и у вас будет, пожалуй, одна копия ваших данных, которая будет такой же, как с использованием другого решения ... – Geoffroy

+0

Кроме того, вы не должны беспокоиться об этом маленьком копировании пока ваша программа не будет работать, и вы определили эту часть как проблему производительности. – Geoffroy

0

Я проводил много исследований, и ответ разбился на две части.

Я был прав в том, что, в отличие от многих других платформ C++, есть простой способ перегрузить существующий класс Gtkmm.

Философия Gtk заключается в том, что фактический объект является дескриптором GObject, а оболочка C++ является лишь одним из многих (Python, Perl и т. Д.). Поэтому даже свойства задаются в дескрипторе через Glib :: Object :: set_property (имя, значение T &) и Glib :: Object :: get_property (имя, значение T &). По сути, GObject - это настоящий «класс».

Так как производный класс и оригинальное общий формат GObject (в данном случае libxml2, объект _xmlDoc), функция обертка стандартного GtkObject должен быть в состоянии передать право собственности, таким образом:

GtkObject *pObj = pGtkObjectBasedClass->c_obj(); 
pMyObjectBasedClass->wrap (pObj); // Automatically increases ref count of object 
delete pGtkObjectBasedClass; 

То есть общий путь. В случае xmlpp не реализована функция «wrap», и она получена из Noncopyable. Однако в новейшем обновлении конструктор, который принимает существующий объект или документ в качестве параметра, теперь является открытым и больше не является частным, поэтому передача теперь должна быть возможна. Нестандартный, но он должен добиться такого же эффекта.

+0

GtkObject будет объектом C (фактически GtkObject не существует в GTK + 3. GObject - это, вероятно, то, что вы имеете в виду). Таким образом, он не имеет метода wrap(). Вы, конечно, не можете просто просто украсть базовый GObject из экземпляров gtkmm. В любом случае, libml не использует GObject, поэтому libxml ++ не использует ту же систему обертывания, что и gtkmm. – murrayc

+0

Вы правы. Я только что открыл это, поэтому моя терминология была немного неустойчивой. – Mike

+0

Дополнительно: много кодирования позже, я обнаружил, что гораздо лучше (и проще в конечном счете) перейти прямо к функциям xmllib2 и написать собственные обертки. Я хочу, чтобы разработчики узнали разницу между оболочкой и каркасом. – Mike

0

Нет, код создает экземпляр xmlpp :: Document, поэтому вы не можете сделать это с помощью libxml ++ без изменения фактического кода libxml ++.

Я действительно не вижу преимущества наличия MyDocument, полученного из xmlpp :: Document. Вы бы не пытались переопределить любое поведение xmlpp :: Document или пытаться добиться какого-либо полиморфизма, и вы бы не писали меньше кода. Фактически, просто использование xmlpp :: Document в качестве переменной-члена вашего класса Document скроет XML-интерфейс нижнего уровня от пользователей вашего класса Document.

 Смежные вопросы

  • Нет связанных вопросов^_^