All header files should have #define guards to prevent multiple inclusion. The format of the symbol name should be
Логичное требование, т.к. вариант с #pragma once windows-specific а нам ведь этого не нужно?
Use forward declarations to minimize use of #include in .h files.
А вот это уже не очень логично. Зачем уменьшать зависимости? Компьютеры у разработчиков слабые? Очень долго компилируют программы? Ну так надо купить новые и проблем не будет. Кто-то из «отцов», то ли Саттер, то ли Александреску (вроде все-таки Александреску) наоборот рекомендовали вместо forward-declaration жахнуть лишний include. Так геморроя будет меньше.
Use standard order for readability and to avoid hidden dependencies: C library, C++ library, other libraries' .h, your project's .h.
#include "foo/public/fooserver.h" // Preferred location.
#include <sys/types.h>
#include <unistd.h>
#include <hash_map>
#include <vector>
#include "base/basictypes.h"
#include "base/commandlineflags.h"
#include "foo/public/bar.h"
Сам уже давно так хидеры расставляю. Получается аккуратненько так.
Unnamed namespaces in .cc files are encouraged. With named namespaces, choose the name based on the project, and possibly its path. Do not use a using-directive.
Особенно порадовало Do not use a using-directive. Удивительно но многим не понятно зачем нужны namespace'ы — чтобы не было конфликта имен. Когда мы используем using, мы собственными руками этот конфликт провоцируем, убивая все бонусы от использования пространств имен. А после того как спровоцировали бежим в какой-нибудь бложик рассказывать какой C++ плохой язык.
Although you may use public nested classes when they are part of an interface, consider a namespace to keep declarations out of the global scope.
Если честно, то не вижу никакого большого смысла делать публичные nested классы. Если он доступен вне класса в котором нестится, то зачем уродовать код? Private nested классы тоже вещь сомнительная — если он виден только в классе в котором определен, то как же реюзабельность этого nested класса?
C++ allows you to declare variables anywhere in a function. We encourage you to declare them in as local a scope as possible, and as close to the first use as possible. This makes it easier for the reader to find the declaration and see what type the variable is and what it was initialized to. In particular, initialization should be used instead of declaration and assignment.
Когда функция представляет изе себя портянку на несколько экранов, то становится уже не важно где объявлены переменные — функция одинаково плохо читается.
Global variables of class types are forbidden. Global variables of built-in types are allowed, although non-const globals are forbidden in threaded code. Global variables should never be initialized with the return value of a function.
При таком подходе придется либо отказаться от синглетонов, либо передавать все синглетоны в объекты/функции (да-да если у вас есть 20 синглетонов то все их передаем в объект или функцию )) ).
Do only trivial initialization in a constructor. If at all possible, use an Init() method for non-trivial initialization.
В общем-то логично. Помнится когда я был маленьким, решил написать свой класс Vector, ну и значит чтобы он работал быстрее, в конструкторе выделял память под 1024 элемента. Потом мне захотелось создать из этих векторов трехмерную матрицу. В общем я не скоро понял почему у меня программа отожрала почти всю память (1000000 вызовов new тому причина). Так что лучше конструкторы делать как можно легче.
You must define a default constructor if your class defines member variables and has no other constructors. Otherwise the compiler will do it for you, badly.
А также конструкторы копирования, деструкторы и операторы присваивания. Либо убедиться, что те функции которые создает компилятор корректно работают.
Composition is often more appropriate than inheritance. When using inheritance, make it public.
Известное в общем-то мнение. Насколько мне кажется, распространено только по одной причине — создать грамотную иерархию классов достаточно сложно.
Only very rarely is multiple implementation inheritance actually useful. We allow multiple inheritance only when at most one of the base classes has an implementation; all other base classes must be pure interface classes tagged with the Interface suffix.
На самом деле существует несколько интересных фокусов с множественным наследованием. Как-нибудь позже расскажу про них.
Do not overload operators except in rare, special circumstances.
Собственно перегрузка операторов практически никогда и не используется. За исключением редких случаев.
Use the specified order of declarations within a class: public: before private:, methods before data members (variables), etc.
Лучше так — public, protected, private. Ну а остальное как описано.
All parameters passed by reference must be labeled const.
Да, const'ами надо чаще пользоваться.
We do not allow default function parameters.
Немного надуманно. Ни у себя в коде проблем с дефолтными параметарами не испытывал ни в какой-либо литературе про эти проблемы не читал.
We do not allow variable-length arrays or alloca().
Истинно так.
We do not use C++ exceptions.
Зря.
Ну там дальше в стандарте идут принципы именования методов и переменных, количество пробелов в табе и прочее. Как я уже писал все эти вещи мне пофиг поэтому за сим закончим.