Google Style Guide in C ++. Teil 8

Teil 1. Einführung
...
Teil 8. Benennung
Teil 9. Kommentare
...



Beim Schreiben von Code wenden wir alle die Regeln des Code-Designs an. Manchmal werden ihre eigenen Regeln erfunden, in anderen Fällen werden fertige Styleguides verwendet. Obwohl alle C ++ - Programmierer einfacher in Englisch als in ihrer Muttersprache lesen, ist es angenehmer, ein Handbuch in letzterer zu haben.
Dieser Artikel ist eine Übersetzung eines Teils des Google Style Guides in C ++ ins Russische.
Originalartikel (Gabel auf Github), aktualisierte Übersetzung .

Benennung


Die Grundregeln für den Codierungsstil sind die Benennung. Die sofortige Darstellung des Namens (ohne nach einer Anzeige zu suchen) sagt uns, was er ist: Typ, Variable, Funktion, Konstante, Makro usw. Namensregeln können beliebig sein, aber Konsistenz ist wichtig, und Regeln müssen befolgt werden.

Allgemeine Namensgrundsätze


  • Verwenden Sie Namen, die auch die Mitglieder des anderen Teams verstehen.
  • Der Name sollte über den Zweck oder die Anwendbarkeit des Objekts sprechen.
  • Speichern Sie nicht die Länge des Namens, es ist besser, einen längeren und verständlicheren Namen (auch für Anfänger) zu haben.
  • Weniger Abkürzungen, insbesondere, wenn sie außerhalb des Projekts nicht bekannt sind.
  • Verwenden Sie nur bekannte Abkürzungen (kennt Wikipedia diese?).
  • Kürzen Sie die Wörter nicht.

Im Allgemeinen sollte die Länge des Namens mit der Größe des Bereichs übereinstimmen. Zum Beispiel ist n ein passender Name innerhalb einer Funktion von 5 Zeilen. Bei der Beschreibung einer Klasse kann dies jedoch etwas kurz sein.

class MyClass { public: int CountFooErrors(const std::vector<Foo>& foos) { int n = 0; //       for (const auto& foo : foos) { ... ++n; } return n; } void DoSomethingImportant() { std::string fqdn = ...; //      } private: const int kMaxAllowedConnections = ...; //     }; 

 class MyClass { public: int CountFooErrors(const std::vector<Foo>& foos) { int total_number_of_foo_errors = 0; //       for (int foo_index = 0; foo_index < foos.size(); ++foo_index) { //   `i` ... ++total_number_of_foo_errors; } return total_number_of_foo_errors; } void DoSomethingImportant() { int cstmr_id = ...; //   ( ) } private: const int kNum = ...; //       }; 

Beachten Sie, dass typische Namen ebenfalls gültig sind: i für einen Iterator oder Zähler, T für einen Vorlagenparameter.

Bei der Beschreibung der Regeln wird in Zukunft nur noch "Wort" / "Wort" in englischer Sprache ohne Leerzeichen, einschließlich Abkürzungen, geschrieben. In einem Wort kann der erste Buchstabe groß geschrieben werden (je nach Stil: " Kamel " oder "Pascal"), die restlichen Buchstaben sind Kleinbuchstaben. Zum Beispiel vorzugsweise StartRpc () , vorzugsweise StartRPC () .

Vorlagenparameter folgen auch den Regeln ihrer Kategorien: Typnamen, Variablennamen usw.

Dateinamen


Dateinamen sollten nur in Kleinbuchstaben geschrieben werden. Sie können Unterstriche ( _ ) oder Bindestriche ( - ) verwenden, um sie zu trennen. Verwenden Sie das im Projekt verwendete Trennzeichen. Wenn es keinen einzigen Ansatz gibt, verwenden Sie "_".

Beispiele für geeignete Namen:

  • my_useful_class.cc
  • my-useful-class.cc
  • myusefulclass.cc
  • myusefulclass_test.cc // _unittest und _regtest sind veraltet.

C ++ - Dateien sollten mit .cc enden, der Header sollte sich in befinden
.h . Dateien, die als Text enthalten sind, müssen mit .inc enden (siehe auch Abschnitt Unabhängige Header ).

Verwenden Sie keine Namen, die bereits in / usr / include vorhanden sind , z. B. db.h.

Versuchen Sie, Dateien bestimmte Namen zu geben. Beispielsweise ist http_server_logs.h besser als logs.h. Wenn Dateien paarweise verwendet werden, ist es am besten, ihnen denselben Namen zu geben. Zum Beispiel foo_bar.h und foo_bar.cc (und enthalten die Klasse FooBar ).

Geben Sie Namen ein


Typnamen beginnen mit einem Großbuchstaben, jedes neue Wort beginnt auch mit einem Großbuchstaben. Unterstriche werden nicht verwendet: MyExcitingClass , MyExcitingEnum .

Namen aller Typen - Klassen, Strukturen, Aliase, Aufzählungen, Vorlagenparameter - werden im gleichen Stil benannt. Typnamen beginnen mit einem Großbuchstaben, jedes neue Wort beginnt auch mit einem Großbuchstaben. Unterstriche werden nicht verwendet. Zum Beispiel:

 // classes and structs class UrlTable { ... class UrlTableTester { ... struct UrlTableProperties { ... // typedefs typedef hash_map<UrlTableProperties *, std::string> PropertiesMap; // using aliases using PropertiesMap = hash_map<UrlTableProperties *, std::string>; // enums enum UrlTableErrors { ... 

Variablennamen


Die Namen von Variablen (einschließlich Funktionsparametern) und Datenelementen werden in Kleinbuchstaben mit einem Unterstrich zwischen den Wörtern geschrieben. Mitglieder dieser Klassen (keine Strukturen) werden durch einen Unterstrich am Ende des Namens ergänzt. Zum Beispiel: a_local_variable , a_struct_data_member , a_class_data_member_ .

Allgemeine Variablennamen


Zum Beispiel:

 std::string table_name; // OK -     

 std::string tableName; //  -   

Klassendatenelemente


Die Mitglieder dieser Klassen, statisch und nicht statisch, werden als gewöhnliche Variablen bezeichnet, wobei am Ende ein Unterstrich hinzugefügt wird.

 class TableInfo { ... private: std::string table_name_; // OK -    static Pool<TableInfo>* pool_; // OK. }; 

Strukturdatenelemente


Die Mitglieder der Strukturdaten, statisch und nicht statisch, werden als reguläre Variablen bezeichnet. Am Ende wird kein Unterstrich hinzugefügt.

 struct UrlTableProperties { std::string name; int num_entries; static Pool<UrlTableProperties>* pool; }; 

Siehe auch Strukturen vs Klassen , in dem beschrieben wird, wann Strukturen und wann Klassen verwendet werden.

Namen von Konstanten


Objekte werden als constexpr oder const deklariert, damit sich der Wert während der Ausführung nicht ändert. Die Namen der Konstanten beginnen mit dem Symbol "k", dann kommt der Name in einem gemischten Stil (Groß- und Kleinbuchstaben). Unterstriche können in seltenen Fällen verwendet werden, wenn Großbuchstaben nicht zur Trennung verwendet werden können. Zum Beispiel:

 const int kDaysInAWeek = 7; const int kAndroid8_0_0 = 24; // Android 8.0.0 

Alle ähnlichen konstanten Objekte mit einem statischen Speichertyp (d. H. Statisch oder global, hier: Speicherdauer ) werden ebenfalls benannt. Diese Konvention ist optional für Variablen in anderen Speichertypen (z. B. automatische Konstantenobjekte).

Funktionsnamen


Gängige Funktionen werden gemischt benannt (Groß- und Kleinbuchstaben). Variablenzugriffsfunktionen (Accessor und Mutator) sollten einen ähnlichen Stil wie die Zielvariable haben.

Normalerweise beginnt ein Funktionsname mit einem Großbuchstaben und jedes Wort im Namen wird in Großbuchstaben geschrieben.

 void AddTableEntry(); void DeleteUrl(); void OpenFileOrDie(); 

(Ähnliche Regeln gelten für Konstanten in einem Klassen- oder Namespace-Bereich, die Teil der API sind und wie Funktionen aussehen sollten (und die Tatsache, dass es sich nicht um Funktionen handelt, ist unkritisch).

Accessoren und Mutatoren (get- und set-Funktionen) können wie die entsprechenden Variablen benannt werden. Sie entsprechen häufig realen Elementvariablen, dies ist jedoch nicht erforderlich. Zum Beispiel int count () und void set_count (int count) .

Namespace Namespace


Der Namespace wird als Kleinbuchstabe bezeichnet. Der Namespace der obersten Ebene basiert auf dem Namen des Projekts. Vermeiden Sie Kollisionen Ihrer Namen und anderer bekannter Namespaces.

Ein Namespace der obersten Ebene ist normalerweise der Name eines Projekts oder Teams (das den Code erstellt hat). Der Code sollte sich in einem Verzeichnis (oder Unterverzeichnis) befinden, dessen Name dem Namespace entspricht.

Vergessen Sie nicht die Regel, keine Abkürzungen zu verwenden - dies gilt auch für Namespaces. Der darin enthaltene Code erfordert wahrscheinlich keinen Namespace-Verweis, sodass Abkürzungen überflüssig sind.

Vermeiden Sie die Verwendung bekannter Namen für verschachtelte Namespaces. Kollisionen zwischen Namen können bei der Montage zu Überraschungen führen. Erstellen Sie insbesondere keine verschachtelten Namespaces mit dem Namen std . Es werden eindeutige Projekt- IDs ( websearch :: index , websearch :: index_util ) empfohlen, anstatt dass diese für Kollisionen unsicher sind. Websearch :: util .

Bei internen / internen Namespaces kann es zu Kollisionen kommen, wenn ein anderer Code hinzugefügt wird (interne Helfer wiederholen sich in der Regel in verschiedenen Teams). In diesem Fall ist es sehr hilfreich, einen Dateinamen zum Benennen eines Namespaces zu verwenden. ( websearch :: index :: frobber_internal zur Verwendung in frobber.h )

Aufzählungsnamen


Aufzählungen (sowohl mit als auch ohne Bereichsbeschränkungen) müssen entweder als Konstanten oder als Makros bezeichnet werden . Das heißt: entweder kEnumName oder ENUM_NAME .

Es ist vorzuziehen, die einzelnen Werte im Enumerator als Konstanten zu benennen. Es ist jedoch zulässig, von Makros zu sprechen. Der Name der UrlTableErrors-Enumeration (und der AlternateUrlTableErrors- Enumeration) selbst ist ein Typ. Folglich wird ein gemischter Stil verwendet.

 enum UrlTableErrors { kOk = 0, kErrorOutOfMemory, kErrorMalformedInput, }; enum AlternateUrlTableErrors { OK = 0, OUT_OF_MEMORY = 1, MALFORMED_INPUT = 2, }; 

Bis Januar 2009 glich die Benennung von Aufzählungswerten der von Makros. Dies führte zu Problemen mit doppelten Makronamen und Aufzählungswerten. Das Anwenden eines konstanten Stils behebt das Problem, und es wird empfohlen, im neuen Code einen konstanten Stil zu verwenden. Es ist jedoch nicht erforderlich, den alten Code neu zu schreiben (sofern kein Duplizierungsproblem vorliegt).

Makronamen


Wirst du keine Makros definieren ? Nur für den Fall (wenn Sie gehen), sollten sie so aussehen:
MY_MACRO_THAT_SCARES_SMALL_CHILDREN_AND_ADULTS_ALIKE .

Lesen Sie bitte, wie Sie Makros definieren . Normalerweise sollten keine Makros verwendet werden. Benennen Sie sie jedoch in Großbuchstaben mit Unterstrichen, wenn Sie sie unbedingt benötigen.

 #define ROUND(x) ... #define PI_ROUNDED 3.0 

Ausnahmen benennen


Wenn Sie etwas benennen müssen, das Analoga in vorhandenem C- oder C ++ - Code enthält, befolgen Sie den im Code verwendeten Stil.

bigopen ()
Funktionsname abgeleitet von open ()

uint
Definition ähnlich Standardtypen

Bigpos
Struktur oder Klasse abgeleitet von pos

sparse_hash_map
STL-ähnliche Entität; folge stl style

LONGLONG_MAX
Konstante wie INT_MAX

Hinweis: Links können zu Teilen des Handbuchs führen, die noch nicht übersetzt wurden.

Source: https://habr.com/ru/post/de477722/


All Articles