Как стать автором
Обновить
1050.52
OTUS
Цифровые навыки от ведущих экспертов

Обзор книги “Beautiful C++: 30 Core Guidelines for Writing Clean, Safe and Fast Code”

Время на прочтение6 мин
Количество просмотров6.1K
Автор оригинала: Sandor Dargo

от Джея Гая Дэвидсона и Кейт Грегори

Если вы знакомы с курсами Кейт Грегори (Kate Gregory) на Pluralsight, то вас не должно удивить название этой книги. Хотя многие считают C++ сложным языком, код которого зачастую очень трудно читать и поддерживать, он все-таки может быть красивым. Я не совру, если скажу, что со всеми нововведениями язык становится все сложнее. Но в то же время множество новых фич языка и его библиотек направлены сделать современный идиоматический код C++ легче в написании и понимании.

Но как писать идиоматический код?

Отличным источником вдохновения могут послужить C++ Core Guidelines, представленные миру на C++ Con в 2015 году. Этот набор рекомендаций редактируется самими Бьерном Страуструпом (Bjarne Stroustrup) и Хербом Саттером (Herb Sutter), но любой желающий может создать пулреквест на Github и волен их критиковать и рецензировать.

Кейт Грегори и Джей Гай Дэвидсон (J. Guy Davidson) были настолько вдохновлены этими рекомендациями, что решили написать о них книгу. К счастью, они не пересказывают все 300 гайдлайнов, а отобрали из них 30 штук, разбили их на 5 групп и подробно разобрали их, не забыв оговорить некоторые связанные с ними нюансы. Цель разбора этих 30 гайдлайнов не в том, чтобы научить вас синтаксису C++, а в том, чтобы улучшить ваш стиль.

Ниже приведены эти пять групп:

  • Bikeshedding — это плохо.

  • Не вредите сами себе.

  • Прекратите это использовать.

  • Используйте эту новую фичу правильно.

  • Сразу пишите хороший код.

Я думаю, что названия этих категорий говорят сами за себя, за исключением первого.

По крайней мере для меня.

Пришлось поискать, что значит bikeshedding (байкшеддинг). Оказывается, Сирил Норткот Паркинсон заметил, что комитет, задачей которого является утверждение планов атомной электростанции, может потратить большую часть своего времени на относительно неважные, но простые для понимания вопросы, например, какие материалы использовать для навеса над велопарковкой (bike shed) для персонала, пренебрегая вопросами конструкции самой электростанции, что намного важнее, но гораздо труднее подвергать конструктивной критике.

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

О чем, собственно, и говорит название раздела! ;)

Помимо названия этого раздела, я думаю, что книга очень ясна и понятна. И ведь непонимание названия скорее является следствием моего уровня владением английского…

Углубимся в детали

Давайте более подробно рассмотрим четыре главы этой книги.

Если это возможно, предпочитайте перегрузке аргументы по умолчанию 

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

Чтение этой главы навсегда устраняет этот пробел в знаниях.

«Прежде чем мы начнем, мы хотим напомнить вам о разнице между параметром и аргументом: аргумент передается в функцию. Объявление функции включает список параметров, один или несколько из которых могут быть снабжены аргументом по умолчанию. Не существует такого понятия, как параметр по умолчанию.»

Ради одного только этого уже стоило прочитать эту главу. Но это еще не все!

F.51 говорит о том, как вы должны делать выбор между аргументами по умолчанию и перегрузкой. В этой главе приводится пример функции make_office(), сложность которой со временем возрастает. С ростом сложности растет и количество параметров функции, и мы узнаем, что может пойти не так. Из-за тонкостей разрешения перегрузки и однозначности аргументов по умолчанию ее перегрузка не рекомендуется.

Однако одна вещь меня удивила. Они не рекомендуют вводить перечисления вместо логических параметров. Но я нашел их контрпример более читабельным, и меня вполне убедил доклад Мэтта Годболта (Matt Godbolt), который также затрагивает этот вопрос.

Тем не менее, я полностью согласен с их окончательным выводом. Если у вас есть такая возможность, предпочитайте вводить новые функции с понятными и описательными именами вместо новых перегрузок, дополнительных bool или enum параметров и аргументов по умолчанию.

Избегайте тривиальных геттеров и сеттеров

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

Но помогает ли это создавать правильные уровни абстракции и взаимодействия между классами?

Я оставлю это вопрос открытым.

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

Как говорится в C.131, мы должны избегать тривиальных геттеров и сеттеров. Они не привносят ничего значимого в интерфейс и не представляют из себя ничего, кроме избыточного кода.

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

В противном случае используйте лучший нейминг, чем простые сеттеры и геттеры. Придумайте абстракции, которые не только выполняют тривиальные задачи, но и гарантируют наличие надлежащих инвариантов класса. Например, вместо void Account::setBalance(int), добавьте в ваш код void Account::deposit(int) и void Account::withdraw(int).

Определяйте концепты

Одной из флагманских фич C++20 являются концепты. Они позволяют формализовать требования к аргументам шаблона. Это фича, которую все мы обязательно должны использовать как можно чаще. Гайдлайны доходят даже до того, что в T.10 говорится, что следует определять концепты для всех аргументов шаблона.

Нам следует формализовать, как будет использоваться аргумент шаблона и какими характеристиками должен обладать тип. Это поможет читателю сразу двумя способами.

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

Если вы хотите узнать больше о концептах, ознакомьтесь с моей книгой C++ Concepts.

Предпочитайте неизменяемые данные изменяемым

И последнее, но не менее важное: давайте немного поговорим о константности.

Гайдлайн P.10 говорит о константности с философской точки зрения. Под этим я подразумеваю, что дело не в том, как и когда вы делаете переменные const. Он скорее о том, что  в терминах неизменяемых данных рассуждать проще. Вы знаете, что несмотря ни на что, они не изменятся.

И на этом гайдлайн P.10 заканчивает мысль. Но глава, посвященная ему, идет гораздо дальше. Авторы предлагают делать объекты и функции-члены const везде, где это возможно. Они также объясняют различия между const-указателями и указателями на const и рассказывают о различиях между east const и west const.

Это немного похоже на короткую версию моей книги How to use const in C++.

В следующей главе они также обсуждают гайдлайн ES.22, который предлагает не объявлять переменную до тех пор, пока у вас не будет значения для ее инициализации. Хотя это не относится непосредственно к константности, они также показывают способы превращения переменных, подпадающих под анти-паттерн [инициализировать, затем изменять], в const-инициализированные. Если кому-то интересно, то это так же просто, как объявить переменную позже, но, возможно, вам придется добавить новый конструктор, использовать тернарный оператор или даже сразу вызываемую лямбду.

В общем, Beautiful C++ предлагает множество способов сделать ваш код более const-корректным.

Заключение

Beautiful C++ — очень интересная книга о том, как писать более читаемый и удобный для сопровождения код на C++. В этой книге вы найдете 30 отобранных гайдлайнов из Core Guidelines. Авторы подробно раскрыли каждый из них, их замысел их применение.

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

В общем, эта книга настоятельно рекомендуется к прочтению!


Отсутствие автоматического сборщика мусора является одним из отличительных свойства таких языков как C++. Завтра вечером состоится открытое занятие по теме «Ручное управление памятью. Достоинства и недостатки», на котором мы рассмотрим:
— Как в этом случае происходит управление памятью.
— Какие преимущества это дает программам на С++.
— И, конечно, какие проблемы привносит и как с ними справляются разработчики с помощью таких идиом языка, как RAII и дополнительных инструментов для обнаружения утечек памяти.
Регистрация доступна по ссылке.

Теги:
Хабы:
Всего голосов 7: ↑5 и ↓2+3
Комментарии4

Публикации

Информация

Сайт
otus.ru
Дата регистрации
Дата основания
Численность
101–200 человек
Местоположение
Россия
Представитель
OTUS