C++ Core Guidelines: различия между версиями

Материал из KONANlabs
Перейти к: навигация, поиск
Строка 25: Строка 25:
 
С точки зрения переносимости и реюзабельности кода, он (код) должен быть написан без использования каких-либо расширений, сторонних библиотек и т. п. Разумеется, на практике это недостижимо - всегда нужно использовать какие-то платформо-зависимые связи (аппаратный ввод-вывод, файлы, базы даных и т. п., не говоря уже о embedded systems). Хорошей практикой является разделение чистой бизнес-логики (которая пишется на ISO C++) и платформо-зависимой части, оформленной в виде интерфейса, к которому обращается бизнес-логика. В этом случае вся работа по портированию сводится к адаптации интерфейса, вместо того, чтобы перепиливать каждый класс.
 
С точки зрения переносимости и реюзабельности кода, он (код) должен быть написан без использования каких-либо расширений, сторонних библиотек и т. п. Разумеется, на практике это недостижимо - всегда нужно использовать какие-то платформо-зависимые связи (аппаратный ввод-вывод, файлы, базы даных и т. п., не говоря уже о embedded systems). Хорошей практикой является разделение чистой бизнес-логики (которая пишется на ISO C++) и платформо-зависимой части, оформленной в виде интерфейса, к которому обращается бизнес-логика. В этом случае вся работа по портированию сводится к адаптации интерфейса, вместо того, чтобы перепиливать каждый класс.
  
Например, мы пишем класс для сложного моргания светодиодом. В классе масса методов, каждый из которых вызывается для выбранного режима моргания. На Arduino непосредственное управление светодиодом реализуется функцией digitalWrite(bool), для управления GPIO платы Raspberry Pi нужно использовать соответствующую библиотеку или вызывать утилиту командной строки. Если создать класс-интерфейс, предоставляющий методы управления GPIO по заранее оговорённой нумерации ног, портирование класса моргания (и всех остальных классов, работающих с GPIO) будет заключаться только в переписывании интерфейса.
+
Например, мы пишем класс для сложного моргания светодиодом. В классе масса методов, каждый из которых вызывается для выбранного режима моргания. На Arduino непосредственное управление светодиодом реализуется функцией digitalWrite(bool), для управления GPIO платы Raspberry Pi нужно использовать соответствующую библиотеку или вызывать утилиту командной строки, и делать эти вызовы в каждом методе управления светодиодом. Если же создать класс-интерфейс, предоставляющий методы управления GPIO по заранее оговорённой нумерации ног, портирование класса моргания (и всех остальных классов, работающих с GPIO) будет заключаться только в переписывании интерфейса.
  
 
=== P.3: Опять самокомментирующийся код ===
 
=== P.3: Опять самокомментирующийся код ===

Версия 22:39, 12 марта 2019

Вольный перевод (скорее, изложение) https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md

P: Философия

P.1: Самокомментирующийся код

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

class myDate {
  year_t year;
  month_t month;
  day_t day;
};

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

day_t period(myDate from, myDate to)

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

P.2: Православные плюсы

С точки зрения переносимости и реюзабельности кода, он (код) должен быть написан без использования каких-либо расширений, сторонних библиотек и т. п. Разумеется, на практике это недостижимо - всегда нужно использовать какие-то платформо-зависимые связи (аппаратный ввод-вывод, файлы, базы даных и т. п., не говоря уже о embedded systems). Хорошей практикой является разделение чистой бизнес-логики (которая пишется на ISO C++) и платформо-зависимой части, оформленной в виде интерфейса, к которому обращается бизнес-логика. В этом случае вся работа по портированию сводится к адаптации интерфейса, вместо того, чтобы перепиливать каждый класс.

Например, мы пишем класс для сложного моргания светодиодом. В классе масса методов, каждый из которых вызывается для выбранного режима моргания. На Arduino непосредственное управление светодиодом реализуется функцией digitalWrite(bool), для управления GPIO платы Raspberry Pi нужно использовать соответствующую библиотеку или вызывать утилиту командной строки, и делать эти вызовы в каждом методе управления светодиодом. Если же создать класс-интерфейс, предоставляющий методы управления GPIO по заранее оговорённой нумерации ног, портирование класса моргания (и всех остальных классов, работающих с GPIO) будет заключаться только в переписывании интерфейса.

P.3: Опять самокомментирующийся код

Оригинальное название правила - "выразить намерение". Те же сопли про читабельность и понимабельность, плюс ссылка на библиотеки gsl и sdtlib. В качестве примера - чем писать цикл while() с явным управлением переменной и условием завершения, читабельнее использовать range-based for. Философия: по возможности, писать что надо сделать, а не как надо это сделать (если "как" уже давно написано в stdlib etc.).

Применимость:

  • диапазонный for вместо обычного;
  • span<T> вместо передачи указателя и размерности;
  • loop variables in too large a scope (?);
  • naked new and delete (?).