![]() |
Модераторы: 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 |
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |