Convenção de Programação
Recomendações para programação em C++.
Baseado em “The Elements of C++ Style - T. Misfeldt, G. Bumgardner, A. Gray”
Namespace
Exemplo
namespace TerraLib
{
....
std::string myString = getName();
....
}
Preprocessador
Use '#include “ … “’ for collocated header files and '#include <…>' for external header files
Place preprocessor include guard (macros associadas a arquivos include) in header files
Use #if. . #endif and #if def . . #endif instead of ”/* . . .*/” comments to hide blocks of code
Use macros sparingly
Do not use “#define” to define constants – declare static const variables instead
Example
#ifndef TE_CONNECTION_POOL_H
#define TE_CONNECTION_POOL_H
....
static const float TeMaxFloat = 3.4e37;
....
#endif // end TE_CONNECTION_POOL_H
Declarações
Use typedefs to simplify complicated type expressions
Create a zero-valued enumerator to indicate an uninitialized, invalid, unspecified or default state
Do not define enumerations using macros or integer constants
Declare enumerations within a namespace or class
Example
typedef std::pair<TeLine, double> TeLineLength;
typedef std::vector<lineLength> TeLineSizes;
enum TeSelectionMode
{
TeSelectionModeDefault, //!< default selection
TeSelectionModeTePointed, //!< object pointed
TeSelectionModeTeQueried, //!< object queried
TeSelectionModeTePointedQueried //!< object pointed and queried
}
Escopo
Example
for (int i = 0; i < 10; i++)
Funções e Métodos
Use an enumeration instead of a Boolean to improve readability
Use an object pointer instead of a reference if a function stores a reference or pointer to the object
Accept objects by reference and primitive or pointer types by value
Pass enumerator values, not integer constants
Do not use void* in a public interface
Use inline functions instead of macros
Inline only the simplest of functions
Classes
Define small classes and small methods
Declare the access level of all members
Declare all member variables private
Avoid the use of friend declarations
Membros de Classes
Declare an explicit default constructor for added clarity
Always declare a copy constructor, assignment operator, and destructor if the class can be instantiated
Always implement a virtual destructor if your class may be subclassed
Make constructors protected to prohibit direct instantiation
Make constructors private to prohibit derivation
Declare a private operator new() to prohibit dynamic allocation
Declare a protected or private destructor to prohibit static or automatic allocation
Declare single-parameter constructors as explicit to avoid unexpected type conversions
Use default arguments to reduce the number of constructors
Do not overload non-virtual methods in subclasses
Declare virtual methods protected and call them from public non-virtual methods
Keep your functions “const-correct“
Use object pointers and references in class declarations
Operadores
Adhere to the natural semantics of operators
Do not overload operator&&() or operator||()
Invoke the superclass assignment operator(s) in the assignment operator of a subclass
Implement copy-safe and exception-safe assignment operators
Define binary operators outside of a class
Implement a Boolean operator in terms of its opposite
Templates
Exemplo
// Example of bad macro
#define MAX(a,b) ( ((a) > (b)) ? (a) : (b) )
// Use template instead
template<class T>
inline T max (const T& a, const T& b)
{
return (a > b) ? a : b/
}
Segurança, Cast e Conversões de Tipos
Use C++ casting operators instead of C-style casts. Ex:
short a = 2000;
int b;
b = (int) a; // c-like cast notation - Ok only for fundamental data types
double d = 3.14159265;
int i = static_cast<int>(d); // No need for this cast
Avoid type casting and do not force others to use it.
Use static-cast<> to impose non-intuitive implicit conversions
Do not use reinterpret-cast<> in portable code
Only use const-cast<> on “this” or when dealing with non-const-correct code
Never use dynamic-cast<> as a substitute for polymorphism
Use dynamic-cast<> to restore lost type information
Always treat string literals as const char*
Use C++ streams instead of stdio function for type safety. Exemplo:
const char* myMessage = "Hello World!!!"; // A string literal
printf("%s", myMessage); // Stdio function
std::cout << myMessage << std::endl; // Use this instead
Test all type conversions
Inicialização e Construção
Initialize all variables
Do not rely on the order of initialization of global objects
Always construct objects in a valid state
Initialize member variables in the initializer list
Initialize member variables in the order they are declared
Indicate when the declaration order of data members is significant
Always list any superclass constructors in the initialize list of a subclass constructor
Do not call virtual functions in constructors and destructors
Declare and initialize static variables within functions
Zero pointers after deletion
Use the new and delete operators instead of malloc() and free()
Declarações e Expressões
Do not rely on operator precedence in complex expressions
Use block statements in control flow constructs
Do not test for equality with true
Replace repeated non-trivial expressions with equivalent methods
Use size-t variables for simple loop iteration and array subscripts
Use a dummy template function to eliminate warnings for unused variables
Fluxo de Controle
Avoid break and continue in iteration statements
Avoid multiple return statements in functions
Do not use goto
Do not use try .. throw .. catch to manage control flow
Never use setjmp() or longjmp() in a C++ program
Always code a break statement in the last case of a switch statement
Manipulação de Erros e Exceções
Use return codes to report unexpected state changes
Use assertions to enforce a programming contract
Do not silently absorb or ignore unexpected runtime errors
Use assertions to report unexpected or unhandled runtime errors
Use exceptions to report errors that may occur under normal program execution
Manage resources with RAII for exception safety
Catch exceptions by reference, not by value
Do not discard exception information if you throw a new exception within a catch block
Avoid throwing exceptions in destructors
Eficiência
Use lazy evaluation and initialization
Reuse objects to avoid reallocation
Leave optimization for last