====== 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 ====== * Usar sempre o namespace **TerraLib** * Usar sempre os namespaces externos explicitamente ===== 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 TeLineLength; typedef std::vector TeLineSizes; enum TeSelectionMode { TeSelectionModeDefault, //!< default selection TeSelectionModeTePointed, //!< object pointed TeSelectionModeTeQueried, //!< object queried TeSelectionModeTePointedQueried //!< object pointed and queried } ====== Escopo ====== * Declare for-loop iteration variables inside of for statements ===== 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 ====== * Use templates instead of macros to create parameterized code * Do not use const or volatile qualified types as template parameters ===== Exemplo ===== // Example of bad macro #define MAX(a,b) ( ((a) > (b)) ? (a) : (b) ) // Use template instead template 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(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