Changes between Version 14 and Version 15 of code/C++_styleguide
- Timestamp:
- Sep 4, 2008, 7:06:28 PM (16 years ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
code/C++_styleguide
v14 v15 11 11 === General === 12 12 Keep your classes/files short, don't exceed 2000 LOC (if it get's longer you may separate functions into different modules). Put every class in a separate file and name the file like the class name (use !CamelCase names). Create a separate header (ends with .h) and source file (ends with .cc). 13 and don't include header files in header files but rather in source files if you can help it.14 13 Example for class {{{MyExampleClass}}}. 15 14 {{{ … … 20 19 21 20 === Headers === 22 Keep your include dependencies in header files as little as possible. Whenever a class member is just a pointer or reference, the forward declaration is sufficient. To make that easier there exists a prerequisites file for each library, containing all the necessary forward declarations. These have to be kept up to date of course.21 Try to minimize header file dependencies by making use of forward declaration and careful dependency studies. Whenever a class member is just a pointer or reference, the forward declaration is sufficient. To make that easier there exists a prerequisites file for each library, containing all the necessary forward declarations. These have to be kept up to date of course. 23 22 Example for a header file include sequence. 24 23 {{{ … … 26 25 27 26 #include <string> // std includes 28 29 27 #include <OgrePrerequisites.h> // most external libraries have forward declaration files as well 30 #include <OgreFrameListener.h> // only include this if you inherit from it or you don't use an object as pointer/reference 31 32 #include "Projectile.h" // our own files, if necessary 33 }}} 34 Note: Never ever (!!!) write {{{using namespace blah;}}} in header files! (think about what it means a little bit) 28 #include "OrxonoxClass.h" // only include this if you inherit from it or you don't use an object as pointer/reference 29 }}} 30 Note: Never ever (!!!) write {{{using namespace foo;}}} in header files! (think about what that would mean) 35 31 36 32 === Source files === 37 Again, keep the dependencies short. However it is not that severe in source files. [br]38 To ensure that every header file can be compiled without additional header dependencies, include class header file first.33 Again, keep the dependencies short. However it is not that severe in source files. [[br]] 34 To ensure that every header file can be compiled without additional header dependencies, include the class header file first. 39 35 Include sequence is for {{{MyClass}}}: 40 36 {{{ … … 43 39 #include <vector> // std headers 44 40 #include <map> 45 46 41 #include <OgreSceneManager.h> // external library headers 47 48 42 #include "BaseObject.h" // our own header files 49 43 }}} 50 44 51 45 === Namespaces === 52 Create a directory for every namespace (== create a directory for every modules and all its submodules). Names representing namespaces should be all lowercase.[[br]]46 Use namespaces for separate libraries like network, 'orxonox' otherwise. Names representing namespaces should be all lowercase.[[br]] 53 47 Don't write "using namespace ..;" in header files because otherwise if someone included that header file, the "using namespace .." would automatically be included as well. That may lead to unwanted errors. 54 48 55 === Inlineing and Templates === 56 Inline functions and template structures should be declared in a .h header file as described above but implemented in a *-inl.h file (since templates are normally not implemented in a source .cc file). 49 === Inlining and Templates === 50 Inline functions and template structures should be declared in a .h header file as described above and implemented below the class declaration if the definition exceeds one line. [[br]] 51 Using the 'inline' keyword within the class declaration doesn't give advantages (it's inline anyway), so let it be. It is necessary outside however. [[br]] 52 An Example: 53 {{{ 54 class FooBar 55 { 56 void funcA() 57 { return this->myVar_; } 58 void funcB(); 59 }; 60 61 inline void FooBar::funcB() 62 { 63 doSomething(); 64 doOtherStuff(); 65 } 66 }}} 67 57 68 58 69 === Machine-Dependent Code === 59 70 Place machine-dependent code in a special file so that it may be easily located when porting code from one machine to another. 60 71 61 === 80 Columns at Maximum===62 File content must be kept within 80 columns. 72 === 80 Columns tops === 73 If you can help it, try to keep your code within 80 character columns, 120 tops otherwise. [[br]] 63 74 ''Comment: 80 columns is a common dimension for editors, terminal emulators, printers and debuggers, and files that are shared between several people should keep within these constraints. It improves readability when unintentional line breaks are avoided when passing a file between programmers.'' 64 75 … … 78 89 Every file that contains source code must be documented with an introductory comment that provides information on the file name and its contents: 79 90 {{{ 80 // 81 }}} 91 /** 92 @file 93 @brief 94 A brief description. 95 More description. 96 */ 97 }}} 98 Note: try not to fill in the filename. It is obvious and the comment compiler (Doxygen) will do it automatically and you don't have to adjust it when renaming the file. 82 99 83 100 == Naming Conventions == 84 101 85 102 === Classes and Types === 86 Names representing types must be in mixed case starting with upper case.103 Names representing types must be in mixed case (CamelCase) starting with upper case. 87 104 {{{ 88 105 class SavingsAccount { … … 129 146 130 147 === Constants === 131 Named constants (including enumeration values) must be all uppercase using underscore to separate words. Always use constants instead of numbers .148 Named constants (including enumeration values) must be all uppercase using underscore to separate words. Always use constants instead of numbers and macros. 132 149 {{{ 133 150 const int MAX_ITERATIONS = 5; … … 144 161 For interface functions to local member variables use short functions (setter and getter functions): 145 162 {{{ 146 class WorldEntity { 163 class WorldEntity 164 { 147 165 public: 148 inline string Name() { 149 return name_; 150 } 151 152 inline void setName(const string& name) { 153 name_ = name; 154 } 166 std::string getName() 167 { return name_; } 168 169 void setName(const std::string& name) 170 { name_ = name; } 155 171 156 172 private: 157 string name_;173 std::string name_; 158 174 }; 159 175 }}} … … 161 177 The name of the object is implicit, and should be avoided in a method name. 162 178 {{{ 163 class Line { 179 class Line 180 { 164 181 public: 165 float getLength(); // Not getLineLength() since it's clear that it is a line.182 float getLength(); // Not getLineLength() since it's clear that it is a line. 166 183 }; 167 184 }}} … … 170 187 Enumeration constants can be prefixed by a common type name. 171 188 {{{ 172 enum Color { 173 COLOR_RED, 174 COLOR_GREEN, 175 COLOR_BLUE 176 }; 189 enum Color 190 { 191 COLOR_RED, 192 COLOR_GREEN, 193 COLOR_BLUE 194 }; 195 }}} 196 However it is better to place an enumeration in a separate namespace. Use 'Enum' as the name of the enum. 197 {{{ 198 namespace Colour 199 { 200 enum Enum 201 { 202 Red, 203 Green, 204 Blue 205 }; 206 } 177 207 }}} 178 208 179 209 === Namespaces === 180 Names representing namespaces should be all lowercase .181 {{{ 182 namespace ioutil {183 210 Names representing namespaces should be all lowercase and consist of one word. 211 {{{ 212 namespace util 213 { 184 214 } 185 215 }}} … … 188 218 == Indentation == 189 219 === Spaces === 190 Use 2spaces for an indentation level. Never use tabs, as it is common in windows IDEs.220 Use 4 spaces for an indentation level. Never use tabs, as it is common in windows IDEs. 191 221 192 222 === Split Lines === … … 206 236 207 237 == Whitespaces == 208 Use one space after each keyword 238 Use one space after each keyword and enclose operators with 2 of them: {{{ if (a + b < c) }}} 209 239 210 240 … … 241 271 floatValue = float(intValue); 242 272 }}} 243 By this, the programmer indicates that he is aware of the different types involved and that the mix is intentional. 244 245 246 === Encapsulation === 273 By this, the programmer indicates that he is aware of the different types involved and that the mix is intentional. [[br]] 274 Note: Never, ever use static_cast or C-Style cast when dealing with multiple or virtual inheritance! 275 276 277 278 === Data Encapsulation === 247 279 Class variables should never be declared public. The concept of C++ information hiding and encapsulation is violated by public variables. Use private variables and access functions instead. One exception to this rule is when the class is essentially a data structure, with no behavior (equivalent to a C struct). In this case it is appropriate to make the class' instance variables public. 248 280 … … 254 286 == Layout == 255 287 === Indentation === 256 Basic indentation should be 2.257 {{{ 258 for (i = 0; i < numberOfElements; i++)259 a[i] = 0;288 Basic indentation should be 4. 289 {{{ 290 for (i = 0; i < numberOfElements; ++i) 291 a[i] = 0; 260 292 }}} 261 293 … … 264 296 Block layout should be as illustrated in this example: 265 297 {{{ 266 while (!done) { 298 while (!done) 299 { 267 300 doSomething(); 268 301 done = moreToDo(); … … 299 332 The if-else class of statements should have the following form: 300 333 {{{ 301 if (condition) { 302 ... 303 } 304 else { 305 ... 306 } 334 if (condition) 335 { 336 ... 337 } 338 else 339 { 340 ... 341 } 342 }}} 343 Never use the token below as it does not, what you expect: 344 {{{ 345 if (condition1) 346 if (condition2) 347 doSomething(); 348 else // This else corresponds to the second if! 349 doSomethingElse(); 307 350 }}} 308 351