**4.** Si le corps entier de la fonction est un `statement` il peut donc être placé sur une seule ligne. Place des espaces autour des accolades (en plus de l’espace à la fin de la ligne).
**15.** Dans les classes et les structures, écrivez `public`, `private`, et `protected` sur le même niveau que `class/struct` et tiret le reste du code.
``` cpp
template <typenameT>
class MultiVersion
{
public:
/// Version of object for usage. shared_ptr manage lifetime of version.
**16.** Si le même `namespace` est utilisé pour l’ensemble du fichier, et il n’y a rien d’autre significatif, un décalage n’est pas nécessaire à l’intérieur `namespace`.
**17.** Si le bloc pour un `if`, `for`, `while` ou autres expressions se compose d’un seul `statement`, les accolades sont facultatives. Place de la `statement` sur une ligne séparée, à la place. Cette règle est également valable pour les imbriqués `if`, `for`, `while`, …
Pour les classes et les structures modélisées, ne séparez pas les déclarations de méthode de l’implémentation (car sinon elles doivent être définies dans la même unité de traduction).
**6.** N’ajoutez pas de commentaires qui ne fournissent pas d’informations supplémentaires. En particulier, ne laissez pas de commentaires vides comme celui-ci:
**7.** Ne pas écrire des commentaires de déchets (auteur, date de création .. au début de chaque fichier.
**8.** Les commentaires sur une seule ligne commencent par trois barres obliques: `///` et les commentaires multi-lignes commencer avec `/**`. Ces commentaires sont pris en considération “documentation”.
REMARQUE: Vous pouvez utiliser Doxygen pour générer de la documentation à partir de ces commentaires. Mais Doxygen n’est généralement pas utilisé car il est plus pratique de naviguer dans le code dans L’IDE.
**3.** Pour les noms de classes (structures), utilisez CamelCase commençant par une lettre majuscule. Les préfixes autres que I ne sont pas utilisés pour les interfaces.
``` cpp
class StorageMemory : public IStorage
```
**4.** `using` sont nommées de la même manière que les classes, ou avec `_t` sur la fin.
**5.** Noms des arguments de type de modèle: dans les cas simples, utilisez `T`; `T`, `U`; `T1`, `T2`.
Pour les cas plus complexes, suivez les règles pour les noms de classe ou ajoutez le préfixe `T`.
``` cpp
template <typenameTKey,typenameTValue>
struct AggregatedStatElement
```
**6.** Noms des arguments constants du modèle: suivez les règles pour les noms de variables ou utilisez `N` dans les cas simples.
``` cpp
template <boolwithout_www>
struct ExtractDomain
```
**7.** Pour les classes abstraites (interfaces), vous pouvez ajouter `I` préfixe.
``` cpp
class IBlockInputStream
```
**8.** Si vous utilisez une variable localement, vous pouvez utiliser le nom court.
Dans tous les autres cas, utilisez un nom qui décrit la signification.
``` cpp
bool info_successfully_loaded = false;
```
**9.** Les noms de `define`les constantes s et globales utilisent ALL\_CAPS avec des traits de soulignement.
``` cpp
#define MAX_SRC_TABLE_NAMES_TO_STORE 1000
```
**10.** Les noms de fichiers doivent utiliser le même style que leur contenu.
Si un fichier contient une seule classe, nommez-le de la même manière que la classe (CamelCase).
Si le fichier contient une seule fonction, nommez le fichier de la même manière que la fonction (camelCase).
**12.** Les arguments du constructeur utilisés uniquement pour initialiser les membres de la classe doivent être nommés de la même manière que les membres de la classe, mais avec un trait de soulignement à la fin.
**14.** Pour les constantes dans un `enum`, utilisez CamelCase avec une lettre majuscule. ALL\_CAPS est également acceptable. Si l’`enum` est non local, utilisez un `enum class`.
**16.** Les abréviations sont acceptables si elles sont bien connues (quand vous pouvez facilement trouver la signification de l’abréviation dans Wikipédia ou dans un moteur de recherche).
Utilisez des exceptions. Dans la plupart des cas, vous avez seulement besoin de lancer une exception, et n’avez pas besoin de l’attraper (à cause de `RAII`).
Dans les serveurs qui gèrent les demandes des utilisateurs, il suffit généralement d’attraper des exceptions au niveau supérieur du gestionnaire de connexion.
Il n’est pas nécessaire d’utiliser une hiérarchie d’exceptions complexe dans le code de l’application. Le texte d’exception doit être compréhensible pour un administrateur système.
- Créer une fonction (`done()` ou `finalize()`) qui vont faire tout le travail en amont qui pourrait conduire à une exception. Si cette fonction a été appelée, il ne devrait y avoir aucune exception dans le destructeur plus tard.
- Les tâches trop complexes (comme l’envoi de messages sur le réseau) peuvent être placées dans une méthode distincte que l’utilisateur de la classe devra appeler avant la destruction.
- Si il y a une exception dans le destructeur, il est préférable de l’enregistrer que de le cacher (si l’enregistreur est disponible).
- Dans les applications simples, il est acceptable de compter sur `std::terminate` (pour les cas de `noexcept` par défaut en C++11) pour gérer les exceptions.
Vous pouvez créer un bloc de code séparé à l’intérieur d’une seule fonction afin de rendre certaines variables locales, de sorte que les destructeurs sont appelés à la sortie du bloc.
- Utiliser le pool de threads pour traiter les demandes. À ce stade, nous n’avons pas eu de tâches nécessitant un changement de contexte dans l’espace utilisateur.
Souvent, il est possible de faire en sorte que différents threads utilisent différentes cellules de mémoire (encore mieux: différentes lignes de cache,) et de ne pas utiliser de synchronisation de thread (sauf `joinAll`).
Dans la bibliothèque `.h` fichier, vous pouvez utiliser `namespace detail` pour masquer les détails d’implémentation non nécessaires pour le code de l’application.
Aussi, un `namespace` peut être utilisé pour un `enum` pour éviter que les noms correspondants ne tombent dans un `namespace` (mais il est préférable d’utiliser un `enum class`).
Si plus tard, vous devez retarder l’initialisation, vous pouvez ajouter un constructeur par défaut qui créera un objet invalide. Ou, pour un petit nombre d’objets, vous pouvez utiliser `shared_ptr/unique_ptr`.
Si la classe n’est pas destinée à une utilisation polymorphe, vous n’avez pas besoin de rendre les fonctions virtuelles. Ceci s’applique également pour le destructeur.
Ne pas utiliser de `iostreams` dans les cycles internes qui sont critiques pour les performances de l’application (et ne jamais utiliser `stringstream`).
`using namespace` n’est pas utilisé. Vous pouvez utiliser `using` avec quelque chose de spécifique. Mais faire local à l’intérieur d’une classe ou d’une fonction.
**26.** Pour les fonctions virtuelles, écrire `virtual` dans la classe de base, mais d’écrire `override` plutôt `virtual` dans les classes descendantes.
**1.** Nous écrivons du code pour une plate-forme spécifique.
Mais toutes choses étant égales par ailleurs, le code multi-plateforme ou portable est préféré.
**2.** Langue: C++17.
**3.** Compilateur: `gcc`. En ce moment (décembre 2017), le code est compilé en utilisant la version 7.2. (Il peut également être compilé en utilisant `clang 4`.)
La bibliothèque standard est utilisée (`libstdc++` ou `libc++`).
**4.**OS: Linux Ubuntu, pas plus vieux que précis.
**6.** Utiliser `-Wall -Wextra -Werror` drapeaux de compilation.
**7.** Utilisez la liaison statique avec toutes les bibliothèques sauf celles qui sont difficiles à connecter statiquement (voir la sortie de la `ldd` commande).
**8.** Le Code est développé et débogué avec les paramètres de version.
## Outils {#tools}
**1.** KDevelop est un bon IDE.
**2.** Pour le débogage, utilisez `gdb`, `valgrind` (`memcheck`), `strace`, `-fsanitize=...`, ou `tcmalloc_minimal_debug`.
**3.** Pour le profilage, utilisez `Linux Perf`, `valgrind` (`callgrind`), ou `strace -cf`.
**4.** Les Sources sont dans Git.
**5.** Assemblée utilise `CMake`.
**6.** Les programmes sont libérés en utilisant `deb` paquet.
**7.** Les Commits à master ne doivent pas casser la construction.
Bien que seules les révisions sélectionnées soient considérées comme réalisables.
Si votre code dans le `master` la branche n’est pas constructible pourtant, l’exclure de la construction avant que le `push`. Vous devrez le terminer ou l’enlever dans quelques jours.
**3.** Vous pouvez installer une bibliothèque qui n’est pas dans les paquets, les paquets n’ont pas ce que vous souhaitez ou avez une version périmée ou le mauvais type de compilation.
**5.** Si possible, n’écrivez pas de constructeurs de copie, d’opérateurs d’affectation, de destructeurs (autres que Virtuels, si la classe contient au moins une fonction virtuelle), de constructeurs de déplacement ou d’opérateurs d’affectation de déplacement. En d’autres termes, les fonctions générées par le compilateur doivent fonctionner correctement. Vous pouvez utiliser `default`.
La raison en est qu’il existe des fonctions non standard similaires, telles que `memmem`. Nous utilisons ces fonctions à l’occasion. Ces fonctions n’existent pas dans `namespace std`.