Я отредактировал ваш вопрос, добавив ссылку на исходный файл, поскольку, очевидно, большинство ответивших здесь не читали его, чтобы увидеть, что на самом деле происходит.Я признаю, что это, вероятно, один из самых запутанных фрагментов кода в FireBreath;в то время я пытался избежать использования boost, и это сработало очень хорошо.
С тех пор я рассмотрел вопрос о переключении на boost :: any (для тех, кто жаждет это предложить, нет, boost :: вариантуне сработает, и я не собираюсь объяснять, почему здесь; задайте еще один вопрос, если вы действительно заботитесь), но мы настроили этот класс на достаточное количество, чтобы сделать его именно тем, что нам нужно, и повысить его: любой будет трудно настроить ваналогичным образом.Больше всего мы следовали старому принципу: если он не сломан, не исправляйте его!
Прежде всего, вы должны знать, что несколько экспертов по C ++ изучили этот код;да, он использует некоторые методы, которые многие считают сомнительными, но они очень тщательно продуманы, и они последовательны и надежны на компиляторах, поддерживаемых FireBreath.Мы провели обширное тестирование с использованием valgrind, визуального детектора утечек, LeakFinder и Rational Purify и никогда не обнаруживали утечек в этом коде.Это более чем сбивает с толку;для меня удивительно, что люди, которые не понимают код, предполагают, что автор не знает C ++.В этом случае Кристофер Диггинс (который написал код, который вы цитировали, и исходный класс cdiggins :: any, из которого он взят), кажется, знает C ++ очень хорошо, о чем свидетельствует тот факт, что он смог написать этот код.Код используется внутренне и высоко оптимизирован - возможно, даже больше, чем нужно FireBreath.Тем не менее, это послужило нам хорошо.
Я постараюсь объяснить ответ на ваш вопрос, насколько я помню;имейте в виду, что у меня не так много времени, и это было какое-то время, так как я действительно углубился в это.Основная причина, по которой «маленькие» типы используют другой статический класс, заключается в том, что «маленькие» типы в значительной степени являются встроенными;int, char, long и т. д. Предполагается, что все, что больше, чем void *, является объектом некоторого рода.Это оптимизация, позволяющая повторно использовать память всякий раз, когда это возможно, а не удалять и перераспределять ее.
Если вы посмотрите на код бок о бок, это будет намного понятнее.Если вы посмотрите на удаление и клонирование, то увидите, что на «больших» объектах оно динамически распределяет память;он вызывает «удалить» в удалении и в клоне он использует обычный «новый».В «маленькой» версии он просто хранит память внутри и повторно использует ее;он никогда не «удаляет» память, он просто вызывает деструктор или конструктор правильного типа в памяти, которая у него есть внутри.Опять же, это просто сделано ради эффективности.При перемещении обоих типов он вызывает деструктор старого объекта и затем назначает данные нового объекта.
Сам объект сохраняется как пустота *, поскольку мы на самом деле не знаем, какого типа будет объект;чтобы вернуть объект обратно, вы должны указать тип.Это часть того, что позволяет контейнеру хранить абсолютно любой тип данных.Вот почему там так много вызовов reinterpret_cast - многие люди видят это и говорят: «О, нет! Автор должен быть невежественным!»Однако, когда у вас есть пустота *, которую вам нужно разыменовать, это именно тот оператор, который вы бы использовали.
В любом случае, все это говорит, что cdiggins фактически выпустил новую версию своего любого класса в этом году;Мне нужно взглянуть на это и, вероятно, попробую вытянуть его, чтобы заменить текущий.Хитрость заключается в том, что я настроил текущую (главным образом, для добавления оператора сравнения, чтобы его можно было поместить в контейнер STL, и для добавления convert_cast), поэтому мне нужно убедиться, что я достаточно хорошо понимаю новую версию, чтобы сделать это безопасно.
Надеюсь, это поможет;статья, из которой я ее получил, находится здесь: http://www.codeproject.com/KB/cpp/dynamic_typing.aspx
Обратите внимание, что статья была обновлена и, по-видимому, больше невозможно получить старую с оригиналом.
EDIT
С тех пор как я написал это, мы подтвердили некоторые проблемы со старым вариантом, и он был обновлен и заменен на тот, который использует boost :: any. Спасибо Дугме за большую часть работы над этим. FireBreath 1.7 (текущая основная ветвь на момент написания этой статьи) содержит это исправление.