System J - C++

Einführung und Literatur zu C++

Coding Standards

Variable, Funktionen und Methoden erhalten immer sprechende Namen.
  • Es besteht kein Grund irgendwas unverständlich abzukürzen.
Namensgebung und Klein- und Großschreibung:
  • Namen von Klassen/Strukturen beginnen grundsätzlich mit "Dbj", es sei denn die Klasse bzw. Struktur ist in eine andere Dbj-Klasse geschachtelt. Es werden keine Unterstriche in den Namen verwendet. Neue Worte werden jeweils mit einem Großbuchstaben begonnen, z.B. "DbjCatalogManager" (und nicht dbj_catalog_manager).
  • Namen von Methoden beginnen immer mit einem Kleinbuchstaben. Vorzugsweise ist das erste Wort im Namen ein Verb. Bestandteile des Namens werden durch einen großen Buchstabe fuer den nächsten Teil getrennt, z.B. "getFreeSpaceMap" (und nicht "get_free_space_map").
  • Variablennamen folgen prinzipiell den gleichen Festlegungen wie fuer Methodennamen.
  • Datentypen werden genau wie Klassen und Strukturen behandelt.
Hinweis: Diese Festlegungen entsprechen im Wesentlichen den Coding Guidelines für Java-Programme.
Alle Members von Klassen und jede Funktion müssen in den Header-Dateien dokumentiert werden. Die Dokumentation wird automatisch mit Doxygen korrigiert, und diese Generation darf keine Warnungen oder Fehler verursachen.
Tracing muss in allen Funktionen und Methoden verwendet werden. Folgendes ist dabei zu beachten:
  • Das Makro DBJ_TRACE_ENTRY muss am Beginn einer jeden Funktion/Methode gesetzt sein.
  • Die Makros DBJ_TRACE_DATA*, DBJ_TRACE_NUMBER oder DBJ_TRACE_STRING sind zu verwenden, wenn wichtige Daten ins Trace geschrieben werden sollen.
Im gesamten Quelltext (ausser in den Testprogrammen) dürfen keine Ein- oder Ausgaben auf Standard-Out oder Standard-Error erfolgen.
Alle Blöcke direkt nach if, while oder for müssen mit { ... } geklammert werden. Dies gilt selbst dann, wenn nur eine eintelne Anweisung in dem Block vorkommt.
Es dürfen keine C-Style Casts verwendet werden. In den meisten Fällen sind Casts ein Zeichen von Programmierfehlern. Wenn Casts benötigt werden, so sind folgende einzusetzen:
static_cast kann für die meisten Casts verwendet werden, wenn die beiden Typen (Quelle und Ziel) kompatibel sind. Der Compiler kann dies weitgehend überprüfen.
reinterpret_cast ist für inkompatible Datentypen zu verwenden; wird aber fast nie benötigt.
const_cast zum Entfernen von const eines Datentypen.
Verwendet const und static wo es möglich und sinnvoll ist. Damit kann der Compiler mehr statische Überprüfungen beim Übersetzen vornehmen.
Setzt Referenzen anstatt Zeiger-auf-Zeigern ein. Der Code wird verständlicher und damit einfacher wartbar. Referenzen sind in der Signatur der jeweiligen Funktion/Methode durch & erkenntlich.
Strukturen/Klassenobjekte können und sollten auch per Referenz übergeben werden, wenn sie nicht NULL (Null-Zeiger) sein können/dürfen. Soll die Struktur in der gerufenen Funktion nicht geändert werden, so verwendet const.
Alle Klassennamen und Funktionen müssen das Präfix "Dbj" tragen.
  • In der Praxis hat oft sogar jede Komponente sein eigenes Präfix.
Alle Compiler-Warnungen müssen vor dem Einchecken des Codes adressiert und beseitigt werden.
Templates, insbesondere die der Standard Template Library (STL) dürfen eingesetzt werden. Exceptions laufen jedoch unserer Fehlerbehandlung zuwieder und dürfen nicht eingesetzt bzw. müssen innerhalb der eigenen Komponente abgefangen und entsprechend für die Fehlerbehandlung DbjError aufbereitet werden.
Gibt eine Funktion einen Fehler mittels DbjErrorCode zurück, so ist immer return DbjGetErrorCode(); zu verwenden, und ein erkannter Fehler muss zuvor mittels DBJ_SET_ERROR* gesetzt bzw. mittels DBJ_TRACE_ERROR getract werden.
Es dürfen keine Funktionen des Betriebssystems direkt verwendet werden. Folgende Ausnahmen bestehen:
strlen Gib Länge eines Strings zurück.
sprintf Formatiere Zahl oder String und schreibe Ergebnis in einen Puffer. Für die Formatierung von Integer-Zahlen existieren die Makros DBJ_FORMAT_*, die in DbjString.hpp definiert sind.
Für alle anderen Betriebssystemfunktionen sind die entsprechenden Funktionen der "Support" Komponente zu verwenden.
Es dürfen nur die Integer-Datentypen Uint32, Sint32, Uint16, Sint16, Uint8 und Sint8 eingesetzt werden.
goto darf (und soll) verwendet werden, um einen zentralen "Exit"-Punkt in einer Funktion/Methode zu erhalten. Das verhindern unnötig tiefe Schachtelungen. Ansonsten gibt es keinen Grund, goto einzusetzen.