C ++ и сериализация: есть ли способ заняться самоанализом?

Я прочитал несколько примеров в Википедии, но я ищу примеры из реальной жизни: как используется интроспекция, почему (помогает ли писать чистый код) и сам код.

Например, есть ли способ создать «универсальную» функцию для сериализации любого объекта? Я имею в виду: только одна функция в родительском элементе, и все потомки могут иметь возможность «сохранять» + «восстанавливать» себя в / из файла.


person Olivier Pons    schedule 15.11.2011    source источник
comment
All is in the question - не лучший способ задать вопрос. Если вы не используете только полностью стандартные термины, вам следует немного объяснить свой вопрос и проиллюстрировать мотивацию, а также указать, что вы пытаетесь получить от этого.   -  person Kerrek SB    schedule 15.11.2011


Ответы (7)


Он не используется (так как его не существует), нет примеров кода (поскольку он не существует), и нет причин пытаться его использовать (поскольку он не существует).

Ближайшее из возможных - это RTTI / dynamic_cast. Но это не совсем самоанализ.

person Puppy    schedule 15.11.2011

В C ++ есть RTTI, и вы также можете использовать для этого условные выражения и dynamic_cast<>(), но в C ++ мы обычно стремимся делать все возможное во время компиляции. Если вы чувствуете потребность в самоанализе, скорее всего, есть лучшие способы достичь того, к чему вы стремитесь, с помощью статического подхода.

person wilhelmtell    schedule 15.11.2011
comment
Если это не звучит для вас убедительно, значит, я расплывчатый. Вы можете быть конкретными, рассказать нам, чего вы пытаетесь достичь? - person wilhelmtell; 15.11.2011

Не совсем. Ближайшее, что у вас будет, - это RTTI. Но посмотрите на метаобъекты Qt, чтобы узнать, как они это сделали (также используя свои _ 1_ генератор).

person Basile Starynkevitch    schedule 15.11.2011

Предлагаю вам изучить boost :: any

http://www.boost.org/doc/libs/1_47_0/doc/html/any.html

person Sga    schedule 15.11.2011
comment
boost :: any - это тип универсальный, но я не понимаю, как это связано с самоанализом ... - person Adrien Plisson; 15.11.2011
comment
Поскольку единственный самоанализ в C ++ касается типов, я подумал, что boost :: any - это хороший пример, и, как OP спросил, это реальный пример с кодом. - person Sga; 15.11.2011
comment
@AdrienPlisson Я не знаю, кто проголосовал против, но boost::any является прекрасным примером того, как самоанализ (как описано в связанной статье в Википедии) используется. В частности, вы можете проверить шаблон any_cast. - person David Rodríguez - dribeas; 15.11.2011
comment
@Sga: если вы начнете свой комментарий с @ и имени, пользователь получит уведомление, что повысит шансы того, что он прочитает ваш комментарий. В любом случае, +1 - person David Rodríguez - dribeas; 15.11.2011
comment
@ DavidRodríguez-dribeas: я проголосовал против. boost :: any не предоставляет никаких встроенных возможностей самоанализа в C ++, это просто хак, который реализует интроспекцию. это как сказать, что C - это динамический язык программирования, поскольку вы можете использовать библиотеку Python C для выполнения некоторого кода Python ... - person Adrien Plisson; 15.11.2011
comment
@AdrienPlisson: Вопрос касается примеров из реальной жизни, где dynamic_cast и / или typeid могут быть использованы для написания чистого кода. В этом ответе содержится ссылка на один из таких примеров: boost::any использует RTTI для написания безопасного кода в any_cast. Как это не ответ? - person David Rodríguez - dribeas; 15.11.2011

Для C ++ существует RTTI, если вам нужно "пойти туда"

Более подробный пример здесь, в Википедии

Обширное обсуждение этой темы уже для справки

person David Wheaton    schedule 15.11.2011

Из связанной статьи видно, что вы имеете в виду typeid и dynamic_cast<>. Вы должны четко указать это в вопросе, так как вскоре вы увидите, что многие люди будут прыгать прямо, не просматривая ссылки.

Теперь, как и когда они используются? Самый простой ответ заключается в том, что обычно это не следует использовать. В большинстве случаев хорошо спроектированная программа не нуждается в проверке типов во время выполнения, и если вы обнаружите, что делаете это, то велика вероятность, что ваш проект в беде.

Конечно, есть исключения из всего, и в частности пример, который дал @Sga, действительно хороший. В boost::any библиотека выполняет стирание типа, чтобы иметь возможность удерживать любой объект внутри типа, а затем использует RTTI вручную в any_cast при извлечении значения, чтобы убедиться, что тип фактического объекта является правильным. Это тоже не является обычным явлением, большинство программ не используют стирание типа, и когда они это делают, им очень редко требуется анализировать тип во время выполнения.

person David Rodríguez - dribeas    schedule 15.11.2011
comment
В большинстве случаев хорошо спроектированная программа не нуждается в проверке типов во время выполнения, и если вы обнаружите, что делаете это, то велика вероятность, что ваш проект в беде. = ›Как можно сериализовать класс (создать универсальную функцию сериализации)? Я считаю, что сериализация - это не плохой дизайн. - person Olivier Pons; 16.11.2011
comment
@OlivierPons Я не говорил, что это никогда не имеет смысла, просто в большинстве случаев это не так. Что касается вашего конкретного примера, я реализовал сериализацию пару раз и не нуждался в ручных проверках RTTI, предоставил виртуальную функцию сериализации и вызвал ее на объекте, тогда динамическая отправка сделает свое волшебство. Обратите внимание, что вам понадобится сериализуемый интерфейс, чтобы в первую очередь иметь возможность вызывать функцию ... - person David Rodríguez - dribeas; 16.11.2011
comment
Да, но то, что вы говорите, подразумевает, что вам все равно нужно реализовать функцию сериализации для каждого дочернего элемента, который хочет иметь возможность сериализовать себя. В Java или Php, благодаря интроспекции, вам просто нужно написать эту функцию один раз (а сериализация / десериализация на самом деле являются частью основных функций php = ›см. php.net/manual/fr/function.serialize.php) - person Olivier Pons; 16.11.2011
comment
@olivierPons: да, согласен, но сейчас вы говорите о другом: отражение должно поддерживаться языком, и оно намного мощнее, чем ручной доступ к RTTI в c ++. C ++ не поддерживает рефлексию. В контексте всех языков приведенное выше предложение будет выглядеть следующим образом: в среде выполнения C ++ проверки типов обычно являются запахом кода. Опять же, как правило, есть несколько примеров, в которых это имеет смысл (boost :: any, например) - person David Rodríguez - dribeas; 16.11.2011

Как уже говорили другие, самоанализ не является особенностью C ++, и самое близкое, что вы можете сделать, это typeid () и dynamic_cast ‹>, но вы действительно не хотите приближаться к этому;)

Тщательная разработка системы владения, передачи и содержания ссылок, использование дизайна на основе политик может использоваться, чтобы избавиться от этой потребности в самоанализе: в строго ООП-мире объекты не обязаны (должны быть) знать свой собственный тип (помимо обеспечения поведения virtual, если так определено).

person zyndor    schedule 15.11.2011