Rules/Notes from "Effective C++", 3rd edition by Scott Meyers

This book is a little outdated, like the use of std::tr1, but still I learned a thing or two - for example, about private inheritance and implicit/explicit conversions.

  1. View c++ as a federation of languages
    • C, Object-Oriented C++, STL, and templates
  2. Prefer consts, enums, and inlines to #defines
  3. Use const whenever possible
  4. Make sure that objects are initialized before they are used
    • Use the constructor member initialization list
    • Use singletons over static global variables
  5. Know what functions c++ silently writes and calls
  6. Explicitly disallow the use of compiler-generated functions you do not want
  7. Declare destructors virtual in polymorphic base classes
    • Only add virtual if the class itself will be used as a parent/base class, as using virtual increases the object's size in memory
  8. Prevent exceptions from leaving destructors
  9. Never call virtual functions during construction or destruction
    • Derived classes are not initialized yet while in the base class ctor
  10. Have assignment operators return a reference to *this
  11. Handle assignment to self in operator=
  12. Copy all parts of an object
  13. Use objects to manager resources
    • Use smart pointers
    • Use RAII technique (resource acquisition is initialization)
  14. Think carefully about copying behavior in resource-managing classes
    • Some options: prevent copying, use resource counter, use deep copy, transfer resource ownership
  15. Provide access to raw resources in resource-managing classes
  16. Use the same form in corresponding uses of new and delete
    • Avoid typedefs using arrays, as it hides wether you need to use delete or delete[] on the typedef'd object
  17. Store new'd objects in smart pointers in standalone statements
  18. Make interfaces easy to use correctly and hard to use incorrectly
  19. Treat class design as type design
  20. Prefer pass-by-reference-to-const to pass-by-value
  21. Don't try to return a reference when you must return an object
  22. Declare data members private
  23. Prefer non-member non-friend functions to member functions
  24. Declare non-member functions when type conversions should apply to all parameters
  25. Consider support for a non-throwing swap
  26. Postpone variable definitions as long as possible
  27. Minimize Casting
    • dynamic casts in particular can be slow
  28. Avoid returning "handles" to object internals
    • Pointers, references, iterators, ...
  29. Strive for exception-safe code
  30. Understand the ins and outs of inlining
  31. Minimize compiliation dependencies between files
    • Avoid using objects when references and pointers will do
    • Depend on class declarations instead of class definitions whenever you can
    • Provide separate header files for declarations and definitions
    • Use abstract interfaces for classes when possible (pimpl paradigm)
  32. Make sure public inheritance models "is-a"
  33. Avoid hiding inherited names
    • Can use 'using ...' to make original base names visible in derived
  34. Differentiate between inheritance of interface and inheritance of implementation
  35. Consider alternatives to virtual functions
    • i.e. template method design pattern, strategy design pattern, std::function objects
  36. Never redefine an inherited non-virtual function
  37. Never redefine a function's inherited default parameter value
    • Default parameters are statically bound as opposed to dynamically bound
  38. Model "has-a" or "is-implemented-in-terms-of" through composition
  39. Use private inheritance judiciously
  40. Use multiple inheritance judiciously
  41. Understand implicit interfaces and compile-time polymorphism
    • Implicit interfaces for templates are based on valid expressions at compile time
  42. Understand the two meanings of typename
    • typename keyword can also be used to specify nested dependent type names
  43. Know how to access names in templatized base classes
    • Can use "this" keyword, add a "using" statement, or add parent namespace (least desirable)
  44. Factor parameter-independent code out of templates
  45. Use member function templates to accept "all compatible types"
  46. Define non-member functions inside templates as friends when type conversions are desired
  47. Use traits classes for information about types
  48. Be aware of template metaprogramming
  49. Understand the behavior of the new-handler
  50. Understand when it makes sense to replace new and delete
  51. Adhere to convention when writing new and delete
  52. Write placement delete if you write placement new
  53. Pay attention to compiler warnings
  54. Familiarize yourself with the standard library, including tr1
  55. Familiarize yourself with Boost

<-- Back to home