Паттерн Шаблонный Метод (Template Method), описанный в книге по паттернам проектирования за авторством “банды четырех” (GoF), не связан с шаблонами (templates) C++ и является поведенческим шаблоном. Curiously Recurring Template Pattern (CRTP или “странно повторяющийся шаблон”) является усовершенствованием паттерна Шаблонный Метод и представляет собой идиому C++, в которой класс X наследуется от реализации шаблонного класса, используя сам X в качестве шаблонного аргумента. Название этой идиоме было дано Джимом Коплиеном (Jim Coplien), который наблюдал ее в самых первых образцах шаблонного кода C++. Эта методика позволяет достигнуть эффекта, аналогичного использованию виртуальных функций, без накладных расходов (и некоторой гибкости) динамического полиморфизма. CRTP можно использовать вместо Шаблонного Метода при условии, что вам не нужен динамический полиморфизм во время выполнения. Этот паттерн широко используется в библиотеках Windows ATL и WTL. Давайте сначала рассмотрим классический паттерн Шаблонный Метод. В своей работе Шаблонный Метод полагается на полиморфизм и, как вы могли догадаться из названия, шаблонный метод. В нашем примере абстрактный базовый класс AbstractTextout имеет 11 перегрузок функции Print и одну чисто виртуальную функцию Process, которая будет реализована только в производных классах. Среди возможных примеров полезных производных классов можно выделить логирование, вывод на консоль и вывод отладочной информации. В этом руководстве мы ограничимся реализацией класса для вывода отладочной информации. Ниже вы можете наблюдать код одной из функций Print. Аргумент Box отвечает за преобразование POD (plain old data) в строку. Отличие от остальных перегрузок функции Print заключается в том, что они просто набивают больше аргументов Box в vs. Я не буду вдаваться в подробности реализации класса Box, так как цель этой статьи заключается в другом. Вы можете посмотреть ее в полном коде примера, ссылки на который приведены в конце статьи. Вот как производный класс DebugPrint реализует функцию Process в DebugPrint.cpp: А так мы взаимодействуем с классом DebugPrint: Для класса с виртуальными функциями создается специальная виртуальная таблица (vtbl). И конечно же наличие виртуальной таблицы подразумевает накладные расходы, связанные с определением правильной функции для вызова. Curiously Recurring Template Pattern же использует статический полиморфизм, который устраняет необходимость в этих накладных расходах. В следующем разделе мы разберемся, за счет чего это достигается. AbstractTextout теперь является шаблонным классом, что означает, что весь код, определенный в cpp, должен быть перемещен в заголовочный файл. Прежде чем вызывать Process, код сначала приводит (cast) себя к производному типу. DebugPrint останется неизменным, за исключением того, что теперь сам является шаблонным типом в своем базовом классе AbstractTextout, и мы должны сделать функцию Process не виртуальной и переместить ее в заголовочный файл: Использовать класс DebugPrint мы будем точно так же, как и раньше: Существует предвзятое мнение, что с C++ даже простую программу писать долго. Современный С++ и набор его библиотек легко могут опровергнуть это. Приглашаю вас на вебинар, где за 40 минут практической части мы создадим настоящий сетевой сервис на языке C++ с использованием библиотеки Boost.Asio. Паттерны проектирования: элементы многоразового объектно-ориентированного программного обеспечения. Википедия по Шаблонному Методу. Википедия по Curiously Recurring Template Pattern. DebugPrint в стиле шаблона с переменным количеством аргументов от автора. Эта статья вместе со всем исходным кодом и файлами находится под лицензией Code Project Open License (CPOL) Загрузить CRTPProj - 7.5 KB Загрузить NonVariadicDebugPrintProj - 8.9 KB  Редактор