Разница между обобщениями и шаблонами С++

Не случайно синтаксис обобщений похож на синтаксис шаблонов С++, тем более что синтаксис всех прочих элементов С# основан на соответствующем синтаксисе С++. Этот подход позволяет опираться на имеющиеся знания. Это типично для С#, потому что проектировщики языка постарались упростить синтаксис и исключить излишнюю многословность. Однако здесь сходство и заканчивается, потому что обобщения С# ведут себя совершенно иначе, чем шаблоны С++, и если вы пришли из мира С++, то должны быть уверенными, что понимаете разницу.

В противном случае может случиться так, что вы станете пытаться применить знания шаблонов С++ таким способом, который просто не будет работать с обобщениями.

Главное отличие между этими двумя средствами в том, что расширение обобщений происходит динамически, в то время как расширение шаблонов С++ является статичным. Другими словами, шаблоны С++ всегда разворачиваются во время компиляции. И одной этой причины достаточно для того, чтобы шаблоны С++ невозможно было поместить в библиотеки.

Начиная изучать шаблоны С++, многие разработчики оказываются разочарованными этим фактом. Существует масса случаев, когда было бы очень здорово иметь возможность упаковывать шаблоны С++ в статические библиотеки или DLL.

К сожалению, это невозможно. Именно поэтому весь код шаблонов С++ обычно располагается в заголовочных файлах. Это затрудняет защиту авторских прав на код шаблонов С++, поскольку, по сути, такой код должен предоставляться в открытом виде любому, кто в нем нуждается. Блестящим примером может служить библиотека STL. Обратите внимание, что почти каждый кусочек реализации STL находится в заголовочных файлах.

С другой стороны, обобщения могут упаковываться в сборки и в таком виде потребляться позже. Вместо формирования во время компиляции конструируемые типы формируются во время выполнения, или, точнее говоря — во время JIT-компиляции. Во многих отношениях это делает их более гибкими. Однако, как почти все в мире разработки, преимущества сопровождаются недостатками.

Обобщения должны трактоваться во время проектирования существенно иначе, чем шаблоны С++.

Всякий раз, когда JIТ-компилятор формирует закрытый тип, для домена приложения инициализируется новый тип. Естественно, это накладывает требования на потребление памяти приложением, также известной под названием рабочего набора (working set).

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

Однако, вообще говоря, эти ограничения минимальны. Если обобщенный тип объявляет массу статических полей, то создание множества закрытых типов на его основе может привести к существенной нагрузке на память, поскольку каждый закрытый тип получает собственную копию набора статических полей. Вдобавок, если эти закрытые типы применяются во многих доменах приложений, то каждый из них также получает свою копию набора статических полей.

Вы можете следить за любыми ответами на эту запись через RSS 2.0 ленту. Вы можете оставить ответ, или trackback с вашего собственного сайта.

Оставьте отзыв

XHTML: Вы можете использовать следующие теги: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

 
Rambler's Top100