![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
а терь для совсем тупых
есть у меня вектор Base'ов. В нем находятся потомки в последовательности: Derived1, Derived2, Derived1, Derived1, Derived2 засериализировать вектор легко КАК его снова получить из потока? как узнать, что для 0-го элемента требуется вызвать Deserialize у Derived1б для 1-го - у Derived2 и т.д.? |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
Сохраняй числовые идентификаторы, по ним определяй что создавать и читать...
|
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
и как сюда приткнуть красивейшую полиморфическую схему, предложенную ранее (имхо, очевидную, ибо вся трудность в этой связке) |
|||
|
||||
| xvr |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 60 Всего: 223 |
Насколько быстро надо? Если умеренно быстро, то можно в качестве ID взять не просто число а пару - строку, с именем типа класса и хэш от этой строки. Если хэш будет достаточно хороший (в идеале без колизий вообще), то определение типа класса сведется просто к индексации массива с хэшами. Реализация: 1) Для получения имен типов используется RTTI 2) Все типы классов должны наследоваться от базового, содержащего примитивы для сериализации 3) Для регистрации классов используется специальный темплэйтный класс - фабрика.
При записи сначала пишется ID класса (хэш(typeid(Item).name()) и typeid(Item).name()), затем сам класс (методом serialize). Опционально можно проверить, что данный ID был зарегистрированн какой либо фабрикой классов (Fabric<xxx>) При чтении читается ID, ищется среди зарегистрированных фабрик (в идеале просто индексируется массив), создается класс, заполняется из потока Это сообщение отредактировал(а) xvr - 18.2.2008, 12:45 |
||||
|
|||||
| marcusmae |
|
||||
![]() stravaganza ![]() ![]() Профиль Группа: Участник Сообщений: 874 Регистрация: 26.3.2006 Репутация: 5 Всего: 39 |
Хорошо, перефразирую. Тип Вы восстановите, я не сомневаюсь (Леонардо да Винчи плакаль бы от приведённых здесь неистовых механизмов осуществления этого). Мне непонятно, что Вы будете делать в случае неоднозначности соответствия сериализованного экземпляра и "места", в которое его нужно десериализовать. Так что, в этой постановке,
ответ : НИКАК. Ещё вопросы? Это сообщение отредактировал(а) marcusmae - 18.2.2008, 13:10 -------------------- ἀπὸ μηχανῆς θεός |
||||
|
|||||
| georain |
|
||||||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 193 Регистрация: 28.11.2006 Где: Санкт-Петербург Репутация: нет Всего: нет |
В общем ничего лучше чем в первом после я не услышал, замечания tol05 относятся к методам сериализации/десериализации, т.е. как упаковать/распаковать класс, это совсем другая проблема. На счёт создания в конструкторе: новый класс можно создавать с параметрами конструктора взятые из потока в той-же функции create().
Надо не забывать что доступ к коду и клиента и сервера одновременно не всегда возможен. Иногда есть только протокол. И третий момент, что не всегда нужно передавать по сети весь класс целиком, часто нужны только некоторые его члены. Была приведена функция
, хорошо, допусти мы работаем по этой методике, как эту функцию Serialize вызвать для нужного класса? tol05 я очень благодарен что хочешь помочь, но мысль совсем не понятна. Ну как тогда без индексов классифицировать классы и вообще отделять один класс от другого в потоке? А изначальная проблема для этой задачи кстати звучит очень просто: есть дерево под сотню классов, набор экземпляров этих классов надо максимально эффективно отправлять по сети, причем последовательность типов экземпляров и их количество заранее не известно. В общем вопрос открытый. P.S. Alek86, кстати строчка
проверят существует ли переменная nNameClass, если ее в enume нет, то ошибку выведет. Поэтому проверка enum'а нужна только на отравляющей стороне (а там проверка находится в функции "сериализации" при вставке константы из enum'а в поток). Добавлено через 13 минут и 29 секунд marcusmae, ну это же может быть вектор указателей на Base) Это сообщение отредактировал(а) georain - 18.2.2008, 13:23 |
||||||
|
|||||||
| tol05 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1632 Регистрация: 21.12.2006 Где: Харьков Репутация: 1 Всего: 170 |
Да действительно, если мы имеем сложный класс MyClass, серилизуем в один и тот же поток 10 его экземпляров, а десерилизовать нужно будет (к примеру) только 2-й и 8-й....
В таком случае, в ф-ции Serealize класса MyClass перед началом записи в поток информации необходимо добавлять метки. Или индексы, как будет угодно Здесь нужно написать базовую функциональность серилизации, а как ее применять - уже зависит от конкретного случая использования... Вот как, например, сказать глупой машине, чтобы среди много-много байтов она нашла только те, которые относятся только к тому классу, у которого 23-й член равен 17? Я описывал только паттерн (композитор ИМХО), реализованный в .Net, в частности. -------------------- На хорошей работе и сны хорошие снятся. |
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
ты не веришь, что десериализация возможна? ) да, похоже... перемудрил я ) тогда порекомендую вместо массива указателей на функции пользовать map и вызов с помощью cdr.getNumber() в try-блок обернуть... Добавлено через 2 минуты и 46 секунд помойму, tol05, ты не совсем понимаешь, в чем вопрос. Вопрос, как отличать разных наследников в списке. Если на это есть "паттерн" - с удовольствием выслушаю (говорю без стеба) |
|||
|
||||
| georain |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 193 Регистрация: 28.11.2006 Где: Санкт-Петербург Репутация: нет Всего: нет |
||||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
чтобы исключения кидать, когда айди несуществующий функция cdr.getNumber() отдаст
в твоем же случае боюсь подумать, что получится. отдастся какое-то число, оно посчитается указателем на функцию и запустится... Добавлено через 1 минуту и 30 секунд а заместо указателей на функции использовать boost::function чтоб и от других ошибок отгородиться |
|||
|
||||
| tol05 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1632 Регистрация: 21.12.2006 Где: Харьков Репутация: 1 Всего: 170 |
Теперь понял. Конечно есть паттерн, как не быть.
каждый объект, серилизуясь, записывает в поток имя своего класса (в качестве своей системной информации, например) Делаем класс - фабрику, куда передаем имя класса и поток. Фабрика создает объект нужного класса. Она ищет в потоке фрагменты данных, соответствующие требуемому классу. Если таких объектов - несколько, перегружаем методы фабрики и добавляем в запросы к фабрике параметры, конкретизирующие поиск. P.S. все, больше мешать не буду. ИМХО решите проблему концептуально сначала. P.S.S указателей не передавайте. Где гарантия уникальности значений? При десерилизации из нескольких потоков? На различных клиентах? Это сообщение отредактировал(а) tol05 - 18.2.2008, 14:27 -------------------- На хорошей работе и сны хорошие снятся. |
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
немного неясная формулировка. короче говоря, нужно делать ту же карту, только между строкой и соответствующей функцией фабрики? тогда это практически то же, что и в первом посте. |
|||
|
||||
| Lazin |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3820 Регистрация: 11.12.2006 Где: paranoid oil empi re Репутация: 41 Всего: 154 |
Ну вы тут напридумывали сами себе сложностей
вот приблизительный код, никаких имен классов, boost::function, и прочего. Похожий код использовал в одном проекте, этот в качестве иллюстрации на коленке написал за пару минут))
|
|||
|
||||
| tol05 |
|
|||
![]() Эксперт ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 1632 Регистрация: 21.12.2006 Где: Харьков Репутация: 1 Всего: 170 |
я бы не сказал, что то же
Похоже конечно, но ведь мы все говорим на одну тему, поэтому и посты как бы об одном и том же... Ты получаешь пакеты данных. Это во-первых. Вначале пакета идет его идентификатор. Замечательно. Получил ты число 12667845 например... Нужно создать какой-то класс. Какой? "с помощью статической функции какого класса"? передаешь принятый пакет (поток) в фабрику. Она считывает из потока блок данных до определенной метки. Это имя класса. Дальше нужно создать экземпляр. Рефлексия в плюсах есть? Позднее связывание? Класс Activator, я имею в виду? marcusmae, здесь точно ответит. я - нет... Но даже если и нет... Простой оператор switch по текстовому значению вызывает ф-цию ISerializable.Deserialize для каждого конкретного класса, а-ля
и т.д. сделайте абстракный класс, как говорилось выше. Если хотите полиморфности. -------------------- На хорошей работе и сны хорошие снятся. |
|||
|
||||
| Alek86 |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1299 Регистрация: 30.1.2007 Где: Киев Репутация: 21 Всего: 25 |
и tol05 и Lazin, фактически, предлагают одно и то же
в С++ нету свича для строк + мап полюбому получше от свича. а у Lazin оно не так автоматизировано, как в пером посте + боюсь представить, что ЭТО такое. какой у этого класса размер?
|
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |