Code Standards
From FreeOrionWiki
Contents |
[edit] General
C++ code should follow modern safe practices wherever possible. Use STL containers whenever appropriate, and avoid C-style arrays. Used std::string rather than c-strings.
Boost library code is available, and should be used whenever appropriate. boost::lexical_cast is quite frequently used, for example.
Class member function declarations should be const-correct.
[edit] Parameters and Return Values
Whenever possible and appropriate, function parameters and return values should be passed:
- For simple built-in data types or very small structures or, for example, std::pair, by value
- For larger data structures or class instances:
- By reference when possible, const if appropriate (ie. the passed value should not be modified)
- By pointer when necessary, const if appropriate.
boost::shared_ptr and similar smart pointers are also available, and may be used when data must be passed by pointer. shared_ptr is also appropriate when returning a shared resource such as a texture that multiple UI elements might display.
If a function produces a lot of output and/or populates a data structure that needs to be returned to the caller, consider passing by reference the structure to be populated as a parameter to the function. This avoids the need to return a large amount of data by value on the stack (as temporary variables in a function cannot be returned by reference or pointer).
[edit] Style
In general, when editing an existing source file, keep the style of code consistent with the rest of the file.
[edit] Naming
Classes should be given UpperCamelCase names, with a leading capitalized letter and words delimited by subsequent capital letters. Do not prepend "C" before class names eg. CNode; use just Node. Use as descriptive and length a class name as appropriate; clarity and specificity are priorities.
Class member functions should also have UpperCamelCase names. eg. PopGrowthProductionResearchPhase()
Class member variables should have m_ prepended to their name, with all lower-case letters and underscores_separating_words. Again, use as long a name as needed to convey the purpose of a variable. eg. m_fleet_id
Class static variables should have s_ prepended before their name, and otherwise be named like member variables. eg. s_current_system_id
Local variables and method parameters should use lower-case letters and underscores to separate words. Use long and descriptive names when appropriate, although occasional single-letter variables names when use and intention is obvious are acceptable, such as loop counters. Do not prepend "p" before pointer variable names, eg. pEmpire; use just empire.
[edit] Internal (Code) Documentation
To add documentation internally with the code usually goes without saying, nevertheless, this project being "open source," seems to make it ever more important to document well.
Generous code comments should have a synergistic effect, and make the entire project better.
Each code block, module, or minor routine, should contain *clear* and descriptive comments within it, describing what the block does.
This is just as important for the coder as it is for others who will view the code, as each programmer knows that he/she might return to correct or refine their code later.
You may want to consider reading Code Complete (a code construction handbook... very good). You may also want to read a short article on PDL which stands for Program Design Language and provides an easy to use methodology to self documenting code.
[edit] Doxygen
Class definitions should contain doxygen-compatible comments for public method and type definitions, and for the classes themselves.
Individual member functions and type declarations may be preceeded or followed-on-the-same-line with comments
class Example {
/** An explanation of a type definition on the line before */
typedef QueueType::iterator iterator;
....
int ReturnValue() const; ///< a comment following a function declaration on the same line
....
/** A function explanation on the lines
* prior to the declaration, which is
* useful for long descriptions.
*/
void DoSomething();
}
Groups of public functions and definitions should be wrapped in group comments.
/** \name Structors */ //@{
Ship(); ///< default ctor
Ship(int empire_id, int design_id); ///< general ctor taking ship's empire and design id; from this the design can be looked up and used to create the ship
//@}
Multiple function declarations and comments in a header file should generally line up to make reading easier. The function names should line up, as when possible, the comments on the same lines should line up vertically.
/** \name Accessors */ //@{
const ShipDesign* Design() const; ///< comment
int FleetID() const; ///< another comment
Fleet* GetFleet() const; ///< yet more comments, all lined up
virtual double ProjectedCurrentMeter(MeterType type) const; ///< the function name was too long, so this comment had to be moved right. This is fine, but try to be consistent when possible.
//@}
[edit] Self-documentation
Aside from clear and consistently-named variables, code may be self-documenting in a few specific situations.
When creating a class which overrides virtual functions inherited from another class, mark the new class's functions virtual as well.

