>S>Язык какой? Элегантность/не элегантность часто зависит от средств, которыми допустимо пользоваться.
>
> C++
>
> S>Ну фабрика для создания объектов потребуется в любом случае (желательно, встроенная в язык
). А вот объект-хозяин — не обязательно.
>
> Вопрос тогда такой: кто должен заниматься чтением/записью типа объекта в/из контейнер(а)?
Все точно так же, как и при сериализации любого другого объекта. Код из буста выглядит так:
template<class Archive, class Container>
struct archive_input_seq
{
inline void operator()(Archive &ar, Container &s)
{
detail::stack_construct<Archive, BOOST_DEDUCED_TYPENAME Container::value_type> t(ar);
// borland fails silently w/o full namespace
ar >> boost::serialization::make_nvp("item", t.reference());
s.push_back(t.reference());
ar.reset_object_address(& s.back() , & t.reference());
}
};
template<class Archive, class U, class Allocator>
inline void load(
Archive & ar,
STD::vector<U, Allocator> &t,
const unsigned int /* file_version */
){
boost::serialization::stl::load_collection<
Archive,
STD::vector<U, Allocator>,
boost::serialization::stl::archive_input_seq<
Archive, STD::vector<U, Allocator>
>,
boost::serialization::stl::reserve_imp<STD::vector<U, Allocator> >
>(ar, t);
}
Если повыкидывать несущественные для понимания сути подробности и тонкости, то останется примерно следующее:
template<class Archive, class U, class Allocator>
inline void load(Archive & ar, STD::vector<U, Allocator> &t, const unsigned int /* file_version */)
{
std::size_t count;
ar >> count;
t.reserve(count);
while (count--)
{
U v;
ar >> boost::serialization::make_nvp("item", v);
t.push_back(v);
}
}
>
> S>Недостаточно гибкая архитектура, на мой взгляд. Зачем объект-хозяин должен хранить указатель на созданный объект и заниматься уничтожением объекта? Ведь ты грузишь объект куда-то — вот там, куда загрузил, его можно и уничтожать впоследствии.
>
> Предполагалось, что хозяин полностью владеет объектом и уничтожает его в своем деструкторе. Создает же объект в методе загрузки, после чтения идентификатора типа. Муть?
Просто неудобно. Допустим, у меня в программе где-то в качестве члена класса используется std::vector<boost::shared_ptr<MyClass> >; Фактически, после загрузки его из файла вашим способом я буду вынужден скопировать его из "объекта-хозяина сериализации" в тот объект, которому он реально нужен, а потом попросить "объект-хозяина сериализации" уничтожить старую копию — поскольку она больше не нужна. Зачем это писать каждый раз, когда это вполне разумное действие можно сделать дефолтным?
> Не понятно, как идеологически правильно: можно сделать, чтобы архив умел сохранять объекты в нужный формат, тогда нужно учить архив работать с разными типами объектов. Можно сделать, чтобы объекты сами умели сохраняться в архив, тогда нужно делать, чтобы они умели сохраняться в архивы разных типов. Кто должен владеть этим кодом?
Архивы умеют сохранять только примитивные типы, а сами объекты либо умеют сохраняться в любой из архивов, предоставляя шаблонные функции save/load/serialize, либо умеют сериализоваться в конкретный тип архива (а им может быть, например, polymorphic_iarchive/polymorphic_oarchive, от которых унаследованы polymorphic_binary_iarchive, polymorphic_text_iarchive, polymorphic_xml_iarchive). Вообще, лучше доку соответствующую посмотрите — там все понятно написано.
Posted via RSDN NNTP Server 2.0
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.