Рекурсивное чтение TCollection - PullRequest
1 голос
/ 21 октября 2010

Я очень плохо отношусь к рекурсии, никогда не использовал ее раньше. Я знаю теорию этого .. не то, что это помогает :)) Для моей проблемы у меня есть структура TCollection, которая содержит TCollection, TCollectionItem и т. Д. Я должен написать рекурсивную функцию, которая будет читать все мои TCollectionItems. Вот графическое представление:

TCollection-> TCollectionItem (s) -> TCollection-> TCollectionItem (s)

TCollection может иметь под ним 1 или даже 2,3 TCollection ИЛИ ни одного.

Вот еще несколько примеров:

TCollection-> TCollectionItem

TCollection-> TCollectionItem-> TCollection-> TCollectionItem-> TCollection-> TCollectionItem

и т. Д.

Пожалуйста, скажите мне, если я описал проблему плохо, я, вероятно, сделал .. пожалуйста, спросите, если что-то неясно:)

Спасибо за поддержку!

Ответы [ 2 ]

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

Единственный способ рекурсивного доступа к дочерним TCollection объектам, не зная типов классов владеющих TCollectionItem объектов, чтобы вы могли их приводить, - использовать информацию RTTI VCL.

В версиях C ++ Builder до XE RTTI на основе VCL доступна только для __published свойств. Имея указатель объекта TCollectionItem (или любой общий TObject), вы можете использовать функцию GetPropList(), объявленную в TypInfo.hpp, для получения списка информации об опубликованных свойствах этого объекта. Затем вы можете перебрать этот список, проверяя любые свойства, которые сообщают значение TypeKind tkClass. Когда вы найдете его, используйте функцию GetObjectProp(), чтобы получить значение указателя TObject этого свойства, а затем используйте dynamic_cast, чтобы убедиться, что это действительно объект TCollection, прежде чем вы получите доступ к его дочерним объектам TCollectionItem.

В C ++ Builder 2010 была представлена ​​новая усовершенствованная система RTTI, объявленная в Rtti.hpp, которая предоставляет информацию для всех членов класса, включая неопубликованные свойства и поля. Благодаря этому расширенному RTTI дочерний элемент TCollection больше не нужно объявлять как свойство __published. В этой системе вы будете использовать класс TRttiContext для доступа к объекту TRttiType для начального объекта TCollectionItem вашей рекурсии, а затем использовать методы TRttiType::GetFields() и TRttiType::GetProperties() для поиска дочерних TRttiField и TRttiProperty элементы, которые сообщают TypeKind tkClass, затем используют методы TRttiField::GetValue() и TRttiProperty::GetValue(), чтобы получить указатель объекта TObject, который может быть приведен к типу к указателю TCollection с dynamic_cast.

1 голос
/ 29 октября 2010

Вы не указали прототипы методов TCollection для перечисления и чтения ваших TCollectionItems и других необходимых деталей.

Однако это определенно решается с помощью: Шаблон составного проекта.

Цель этого паттерна - пройти рекурсивную форму и переадресовать вызов композита на его композиты и так далее, пока он не достигнет листьев (TCollectionItems с пустой TCollection вслучай)

...