Возвращение к C++ (современный C++)
C++ является одним из наиболее широко используемых языков программирования в мире. Грамотно сконструированные программы на языках C++ быстры и эффективны. Язык является более гибким, чем другие языки, поскольку его можно использовать для создания широкого спектра приложений — от интересных и ярких игр до высокопроизводительного научного программного обеспечения и драйверов устройств, внедренных приложений и клиентских приложений Windows. Более 20 лет C++ используется для решения подобных и многих других задач. Возможно, вы не знаете, что все больше программистов С++ отказались от программирования вчерашнего дня в C-стиле и перешли к современной модели программирования С++.
Одно из начальных требований для C++ — обратная совместимость с языком C. С этого момента язык C++ эволюционировал через несколько итераций — C с классами, исходная спецификация языка C++ и множество последовательных усовершенствований. Из-за этого наследия C++ часто называют мультипарадигматическим языком программирования. В C++ доступны чисто процедурное программирование в C-стиле, которое содержит необработанные указатели, массивы, строки с конечным символом null, пользовательские структуры данных и другие компоненты, которые могут обеспечить высокую производительность или стать причиной ошибок и чрезмерной сложности кода. Поскольку программирование в стиле языка C чревато подобными опасностями, одной из основных целей создания C++ было сделать программы как типобезопасными, так и более простыми в написании, расширении и сопровождении. Уже на ранних этапах развития в языке C++ были полностью реализованы такие парадигмы программирования, как объектно-ориентированное программирование. С годами к этому языку были добавлены функции и стандартные библиотеки структур данных и алгоритмов, прошедшие тщательное тестирование. Именно благодаря этим дополнениям появился и существует современный стиль C++.
Современный язык C++ обеспечивает следующие возможности:
Область стека вместо кучи или статической глобальной области.
Автоматическое определение типа вместо явных имен типов.
Интеллектуальные указатели вместо необработанных указателей.
Типы std::string и std::wstring (см. <string>) вместо необработанных массивов char[].
Стандартная библиотека шаблонов (STL) содержит такие контейнеры как vector, list и map, а не необработанные массивы пользовательских контейнеров. См. <vector>, <list> и <map>.
Алгоритмы STL вместо закодированных вручную.
Исключения для сообщения о состояниях ошибки и их обработки.
Свободное от блокировок взаимодействие между потоками с помощью STL std::atomic<> (см. <atomic>) вместо других механизмов взаимодействия между потоками.
Встроенные лямбда-функции вместо небольших функций, реализованных отдельно.
Конструкции на основе диапазонов для циклов, позволяющие создавать более надежные циклы, которые работают с массивами, контейнерами STL и коллекциями Среда выполнения Windows в форме for ( for-range-declaration : expression ). Это часть базовой языковой поддержки. Для получения дополнительной информации см. Основанное на диапазоне выражение for (C++).
Сам язык C++ также развивался. Сравните следующие фрагменты кода. Этот фрагмент показывает, как обстояли дела в C++ раньше:
// circle and shape are user-defined types
circle* p = new circle( 42 );
vector<shape*> v = load_shapes();
for( vector<circle*>::iterator i = v.begin(); i != v.end(); ++i ) {
if( *i && **i == *p )
cout << **i << “ is a match\n”;
}
for( vector<circle*>::iterator i = v.begin();
i != v.end(); ++i ) {
delete *i; // not exception safe
}
delete p;
А этот фрагмент показывает, как та же задача решается в C++ сейчас:
#include <memory>
#include <vector>
// ...
// circle and shape are user-defined types
auto p = make_shared<circle>( 42 );
vector<shared_ptr<shape>> v = load_shapes();
for_each( begin(v), end(v), [&]( const shared_ptr<shape>& s ) {
if( s && *s == *p )
cout << *s << " is a match\n";
} );
В современном C++ не следует использовать операторы new и delete или явную обработку исключений, поскольку вместо этого можно использовать интеллектуальные указатели. При использовании вычета типа auto и лямбда-функции можно написать код быстрее, сделать его более сжатым и понятным. Кроме того, цикл for_each проще и удобнее в использовании, а также в меньшей степени подвержен непреднамеренным ошибкам, чем цикл for. Можно использовать для написания приложения стандартный текст и минимум строк кода. Кроме того, этот код можно сделать безопасным в отношении исключений и в отношении памяти, исключая необходимости обрабатывать выделение и освобождение или коды ошибок.
Современный C++ включает два типа полиморфизма: во время компиляции, с помощью шаблонов, и в среде выполнения, путем наследования и виртуализации. В целях повышения эффективности можно объединить два типа полиморфизма. Шаблон STL shared_ptr использует внутренние виртуальные методы для выполнения удалений без усилий. Однако не злоупотребляйте виртуализацией для полиморфизма, если лучше использовать шаблон. Шаблоны могут быть очень мощными.
Если вы начинаете работать с С++ после другого языка, особенно после управляемого языка, в котором большинство типов — ссылочные типы, и лишь немногие — типы значений, знайте, что классы С++ — это типы значений по умолчанию. Однако можно указывать их как ссылочные типы для получения полиморфного поведения, которое соответствует концепции объектно-ориентированного программирования. Удобно представлять это себе так: типы значений относятся, скорее, к управлению памятью и макетом, ссылочные типы относятся, скорее, к базовым классам и виртуальным функциям для поддержки полиморфизма. По умолчанию типы значений являются копируемыми — каждый из них имеет конструктор копии и оператор присваивания копированием. При определении ссылочного типа сделайте класс недоступным для копирования, отключив конструктор копий или оператор назначения копирования и воспользовавшись виртуальным деструктором, поддерживающим полиморфизм. Типы значений также связаны с содержимым, то есть, если они копируются, необходимо предоставить два независимых значения, которые можно изменить по отдельности. Однако ссылочные типы, скорее, связаны с идентификацией — какой это объект — и иногда из-за этого называются полиморфными типами.
C++ переживает возрождение, потому что мощность снова становится приоритетом. Языки, например Java и C#, хорошо подходят, если важна продуктивность программиста, однако как только речь заходит о мощности и производительности, становятся очевидными их ограничения. Для повышения эффективности и мощности, особенно для устройств с ограниченным оборудованием, ничто не подходит лучше, чем современный С++.
Современен не только язык, но и средства разработки. Visual Studio делает все части цикла разработки надежными и эффективными. Он включает средства управления жизненным циклом приложения (ALM), усовершенствования интегрированной среды разработки, такие как IntelliSense, совместимые со средствами механизмы, такие как XAML, а также сборки, отладки и многие другие средства.
Статьи в этом разделе документации содержат общие правила и рекомендации по наиболее важным функциям и методам для записи современных программ на языке C++.
Подробнее см. в следующей статье на сайте StackOverflow: Какие идиомы C++ не рекомендуется использовать в C++11