[БЕЗ_ЗВУКА] Итак, мы с вами изучили константность в C++ и посмотрели, как она позволяет существенно повысить качество, надежность, а иногда и быстродействие вашего кода. И в этом видео давайте подведем итоги, просуммируем весь изученный материал и сформулируем рекомендации по использованию константности в программах на C++. Мы говорили, что константность защищает от случайного изменения объектов в программах. И из этого свойства часто делают такую рекомендацию. Говорят, что делайте константными все переменные, какие только можете. Но на самом деле, на мой взгляд, это не самая лучшая рекомендация. Дело в том, что слово const — это пять символов, после которых еще идет пробел. Это шесть символов всего, и если чрезмерно использовать const при объявлении переменных, то программа становится слишком громоздкой. Поэтому наши рекомендации заключаются в том, чтобы искать золотую середину между двумя на самом деле немного противоречащими друг другу советами. Первый совет заключается в том, что если переменная не изменяется, то объявляйте ее константной, а второй совет — не загромождайте ваш код. Вот давайте рассмотрим простой пример. У нас есть функция Area, которая считает площадь треугольника по трем сторонам с помощью формулы Герона. И мы в ней объявляем переменную p, которая хранит в себе полупериметр, и эта переменная только читается. Мы ее объявили, проинициализировали и только читаем в этой функции. И поэтому мы объявляем ее константной — потому что мы не собираемся ее изменять. Ну, вроде бы вполне нормально, код легко читается и не захламлен. Но можно эту функцию написать и вот так. Можно сказать, что наши входные параметры a, b и c тоже не изменяются, мы из них тоже читаем. И поэтому давайте их сделаем тоже константными. Но вот на мой субъективный взгляд, это уже перебор, потому что у нас маленькая функция, всего из двух строчек. И из нее очевидно, что мы вот эти параметры a, b и c не меняем. Но вместо этого ее объявление стало довольно большим, оно распухло на целых 18 символов, и поэтому, на мой взгляд, вот это уже перебор. Но давайте вспомним другой пример и другое свойство константности. Мы говорили, что у нас в программах часто бывают объекты, которые обладают какими-то дополнительными свойствами. И мы это разбирали на примере отсортированного вектора. Так вот, для объектов, которые обладают какими-то дополнительными свойствами, не присущими их классам, делать такие объекты константными очень и очень полезно, потому что вы позволяете проще понимать ваш код и вы делаете так, что вам язык, вам компилятор, гарантирует, что вот это дополнительное свойство у объекта не пропадет в течение его жизни. Дальше. Мы с вами познакомились с идиомой Immediately-invoked lambda expression. И мы вам советуем пробовать использовать эту идиому, когда вам нужно создать константный объект с какой-то нетривиальной инициализацией. Эта идиома не всегда приводит к тому, что у вас получается хороший, понятный, легко читаемый код, поэтому совет именно такой, что пробуйте. Попробуйте, посмотрите, что получится. Если это вас не устраивает, то воспользуйтесь какими-то другими способами, например, напишите отдельную функцию, которая выполняет вот эту нетривиальную инициализацию. И где идиома IILE незаменима, так это в ситуациях, когда нам нужно померить время, которое уходит на конструирование объекта. Мы начинали наш модуль с примера, в котором мы стали изменять поле объекта и из-за этого убрали константность у метода. Так вот, наша рекомендация состоит в том, чтобы никогда не снимать константность у методов, которые по своему смыслу не должны изменять объект. Если вам нужно в константных методах что-то изменять, то, во-первых, возможно, вы делаете что-то не так, а во-вторых, есть ключевое слово mutable, которое позволяет изменять поля в константных методах. Однако хочется сразу вас предостеречь от соблазна объявлять все свои поля как mutable. В этом случае вы нарушаете гарантии, которые даются константными методами. Мы говорили: константный метод не меняет наблюдаемое состояние объекта. Поэтому если вы пометите ключевым словом mutable поле, которое относится к наблюдаемому состоянию объекта, вы будете врать своим пользователям, и вашим классом нельзя будет пользоваться из-за того, что константные методы не будут выполнять своих гарантий. В моем опыте есть только два сценария, когда ключевое слово mutable применимо: это кэши и это мьютексы. Оба примера мы с вами рассмотрели в нашем уроке про константность. И вот если вы хотите применить ключевое слово mutable в какой-то другой ситуации, не для кэширования каких-то результатов и не для обеспечения внутренней синхронизации объекта, три раза подумайте, правильно ли вы делаете, нельзя ли поступить как-то иначе. Ну и подходя к завершающим частям нашего урока, давайте еще раз вспомним, что в многопоточных программах нам нет необходимости выполнять синхронизацию доступа к константным объектам. Поэтому если ваш класс предназначен для использования в многопоточной среде и в нем есть mutable поля, гарантируйте, обеспечьте, что эти mutable поля потокобезопасны, потому что вам необходимо обеспечить свойство вашего класса, которое заключается в том, что константность гарантирует потокобезопасность и при доступе к константным объектам нет обходимости выполнять внешнюю синхронизацию.