Рекурсивное чтение TCollection
Я очень плохо с рекурсией, никогда не использовал его раньше. Я знаю эту теорию.. не то, чтобы это помогло:)) Для моей проблемы у меня есть структура TCollection, которая содержит TCollection, TCollectionItem и т. Д. Я должен написать рекурсивную функцию, которая будет читать все мои TCollectionItems. Вот графическое представление:
TCollection-> TCollectionItem (s) -> TCollection-> TCollectionItem (s)
TCollection может иметь 1 или даже 2,3 TCollection под ним ИЛИ ни одного.
Вот еще несколько примеров:
TCollection-> TCollectionItem
TCollection-> TCollectionItem-> TCollection-> TCollectionItem-> TCollection-> TCollectionItem
так далее..
Пожалуйста, скажите мне, если я описал проблему плохо, я, вероятно, сделал.. пожалуйста, спросите, если что-то неясно:)
Спасибо за поддержку!
2 ответа
Вы не указали прототипы методов TCollection, чтобы перечислять и читать ваши TCollectionItems и другие необходимые детали.
Тем не менее, это определенно решается с помощью: Composite Design Pattern.
Цель этого шаблона - пройти рекурсивную форму и переадресовать вызов композита на его составные компоненты и т. Д., Пока он не достигнет листьев (TCollectionItems с пустым TCollection в вашем случае)
Единственный способ рекурсивного доступа ребенка 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 была представлена новая система Enhanced 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
,