C ++ специфические шаблоны из-за языкового дизайна - PullRequest
10 голосов
/ 27 января 2010

Мне потребовалось много времени, чтобы понять, насколько важны и тонки переменные, которые:

1) существует в стеке

2) их деструкторам называют, когда они выпадают из области видимости

есть.

Эти две вещи допускают такие вещи, как:

A) RAII

B) пересчитан GC

Интересно, что (1) и (2) недоступны на «более низких» языках, таких как C / Assembly; ни в «более высоких» языках, таких как Ruby / Python / Java (поскольку GC предотвращает предсказуемое уничтожение объектов).

Мне любопытно - какие другие техники, о которых вы знаете, очень специфичны для C ++, из-за выбора дизайна языка.

Спасибо!

Редактировать: Если ваш ответ "это работает в C ++ и это другой язык", это тоже хорошо. Вещи, о которых я хочу узнать, похожи на:

Выбирая отсутствие определенных функций (например, GC), мы получаем другие функции (например, RAII + предсказуемое разрушение объектов). В каких областях C ++, выбирая для NOT функции, которые есть в других языках «более высокого уровня», C ++ удается получить шаблоны, которые эти языки более высокого уровня не могут выразить.

Ответы [ 7 ]

7 голосов
/ 27 января 2010

странно повторяющийся шаблон

шаблоны выражений

Вероятно, вся концепция метапрограммирования также

3 голосов
/ 27 января 2010

Я действительно люблю классы черт. Не совсем специфичный для C ++ (в других языках, таких как Scala), но он позволяет вам адаптировать объекты, в основном, для указания набора операций, которые должен поддерживать тип. Представьте, что вам нужен «хешер», в смысле tr1::hash. Хеш определен для некоторых типов, но не для других. Как вы можете создать класс, у которого есть хеш, определенный для всех типов, которые вы хотите? Вы можете объявить класс, такой как:

template < typename T>
struct hashing_tratis
{
    typedef std::tr1::hash<T> hashing_type;
};

то есть вы ожидаете, что класс с правильным определенным типом hasing_ будет использоваться. Однако хеш не определен, скажем, для myType, поэтому вы можете написать:

template <>
struct hashing_traits<myType>
{
    typedef class_that_knows_how_to_hash_myType hashing_type;
};

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

template <typename T>
struct something {
    typename hashing_traits<T>::hashing_type hasher;
    .... // here hasher is defined for all your relevant types, and knows how to hash them
2 голосов
/ 27 января 2010
  • Всегда возлагать на вызывающего абонента ответственность за распределение / освобождение памяти, что означает, что код, который будет выглядеть следующим образом в Java / C #:

    MyClass doSomething(MyClass someInstance);
    

    выглядит так в C / C ++:

    void doSomething(MyClass* someBuffer, MyClass* someInstance);
    
  • Использование деструкторов для закрытия сокетов, файловых дескрипторов и т. Д.
2 голосов
/ 27 января 2010

Что ж, это можно сделать на языке программирования D, а также на двух упомянутых вами языках, но шаблоны, достаточно мощные для того, чтобы по существу функционировать как ввод во время компиляции , довольно полезны. Я часто чувствую, что большая часть дебатов между статическими и динамическими языками может быть решена с помощью достаточно хорошей системы шаблонов, так что, хотя типы должны быть статически разрешены во время компиляции, их не нужно знать во время разработки. C ++ впервые применил эту идею (по крайней мере, среди основных языков). D делает еще несколько шагов вперед.

Благодаря шаблонам и типизированной утке во время компиляции вы получаете лучшее из обоих миров: гибкость в том, что вам не нужно указывать типы во время разработки функции или класса, а также безопасность и производительность их знания во время компиляции.

1 голос
/ 07 ноября 2012

Есть идиома pImpl. Он работает аналогично шаблону Bridge.

И шаблон выражений , который задерживает вычисления выражений в C ++.

Эти две работы также исследуют этот вопрос: Больше идиом C ++ и Эффективный C ++ (Scott Meyers, 2005)

1 голос
/ 27 января 2010

Ну, почти ВСЕ «шаблоны проектирования» имеют сильную связь с C ++. Скорее, вы должны предположить, что они НИЧЕГО не имеют отношения к «правильному дизайну» и «лучшим практикам», а ВСЕ - к причудливым слабостям C ++ и тщательно обдумать реальную необходимость любого из них вместо того, чтобы бездумно усложнять ваш код. Тем более, что многие из шаблонов проектирования - это бинты, чтобы исправить проблемы, создаваемые другими шаблонами проектирования. Это применимо в десять раз больше, чем при использовании любого языка, кроме C ++, поскольку в C ++ существует огромное количество проблем, которых нет в других языках.

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

То же самое относится к шаблону моста, я могу видеть использование синглетонов, но просто нет причин когда-либо использовать шаблон моста. Все сводится к тому, что «ты знаешь, что делаешь?». Если это так, вам не нужен шаблон моста. Если нет, вам, вероятно, следует узнать больше, прежде чем пытаться решить проблему, побуждающую вас использовать шаблон моста. Самое главное, что это не очень полезно для языков, кроме C ++. Смысл этого в том, чтобы отделить реализацию и интерфейс, что в более современных языках ОО уже сделано, потому что у них есть собственные модули определенного типа. В C ++ лучше использовать чистые виртуальные интерфейсы для подобных случаев (и не думайте, что это имеет худшую производительность, она имеет гораздо лучшую производительность, чем шаблон моста в сочетании с шаблонами).

Но это проблема шаблонов проектирования; это вовсе не методология, просто куча случайных вещей. Случайные вещи, которые большинство людей, защищающих их, на самом деле не понимают, большинство из которых должным образом не имеют никакого места, называемого чем-либо со словом «дизайн». Это не инструменты проектирования, а конкретные решения различных проблем. Многие из которых можно избежать.

По иронии судьбы, Java-API полон мостов и множества других шаблонов проектирования, которые абсолютно бессмысленны в Java. Java API прост в использовании в большинстве случаев, но слишком сложная иерархия может быть очень громоздкой для работы.

0 голосов
/ 27 января 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...