預覽 Herb Sutter 及 Andrei Alexandrescu 的新書《C++ Coding Standards》。

還沒有機會去書店買,但從 Amazon.com 裡的評論看來,這本書與 Effective C++ 似乎頗有互補作用。

  1. Don’t sweat the small stuff. (Or: Know what not to standardize.) 2
  2. Compile cleanly at high warning levels. 4
  3. Use an automated build system. 7
  4. Use a version control system. 8
  5. Invest in code reviews. 9
  6. Give one entity one cohesive responsibility. 12
  7. Correctness, simplicity, and clarity come first. 13
  8. Know when and how to code for scalability. 14
  9. Don’t optimize prematurely. 16
  10. Don’t pessimize prematurely. 18
  11. Minimize global and shared data. 19
  12. Hide information. 20
  13. Know when and how to code for concurrency. 21
  14. Ensure resources are owned by objects. Use explicit RAII and smart pointers. 24
  15. Prefer compile- and link-time errors to run-time errors. 28
  16. Use const proactively. 30
  17. Avoid macros. 32
  18. Avoid magic numbers. 34
  19. Declare variables as locally as possible. 35
  20. Always initialize variables. 36
  21. Avoid long functions. Avoid deep nesting. 38
  22. Avoid initialization dependencies across compilation units. 39
  23. Minimize definitional dependencies. Avoid cyclic dependencies. 40
  24. Make header files self-sufficient. 42
  25. Always write internal #include guards. Never write external #include guards. 43
  26. Take parameters appropriately by value, (smart) pointer, or reference. 46
  27. Preserve natural semantics for overloaded operators. 47
  28. Prefer the canonical forms of arithmetic and assignment operators. 48
  29. Prefer the canonical form of ++ and –. Prefer calling the prefix forms. 50
  30. Consider overloading to avoid implicit type conversions. 51
  31. Avoid overloading &&, ||, or , (comma). 52
  32. Don’t write code that depends on the order of evaluation of function arguments. 54
  33. Be clear what kind of class you’re writing. 56
  34. Prefer minimal classes to monolithic classes. 57
  35. Prefer composition to inheritance. 58
  36. Avoid inheriting from classes that were not designed to be base classes. 60
  37. Prefer providing abstract interfaces. 62
  38. Public inheritance is substitutability. Inherit, not to reuse, but to be reused. 64
  39. Practice safe overriding. 66
  40. Consider making virtual functions nonpublic, and public functions nonvirtual. 68
  41. Avoid providing implicit conversions. 70
  42. Make data members private, except in behaviorless aggregates (C-style structs). 72
  43. Don’t give away your internals. 74
  44. Pimpl judiciously. 76
  45. Prefer writing nonmember nonfriend functions. 79
  46. Always provide new and delete together. 80
  47. If you provide any class-specific new, provide all of the standard forms (plain, in-place, and nothrow). 82
  48. Define and initialize member variables in the same order. 86
  49. Prefer initialization to assignment in constructors. 87
  50. Avoid calling virtual functions in constructors and destructors. 88
  51. Make base class destructors public and virtual, or protected and nonvirtual. 90
  52. Destructors, deallocation, and swap never fail. 92
  53. Copy and destroy consistently. 94
  54. Explicitly enable or disable copying. 95
  55. Avoid slicing. Consider Clone instead of copying in base classes. 96
  56. Prefer the canonical form of assignment. 99
  57. Whenever it makes sense, provide a no-fail swap (and provide it correctly). 100
  58. Keep a type and its nonmember function interface in the same namespace. 104
  59. Keep types and functions in separate namespaces unless they’re specifically intended to work together. 106
  60. Don’t write namespace usings in a header file or before an #include. 108
  61. Avoid allocating and deallocating memory in different modules. 111
  62. Don’t define entities with linkage in a header file. 112
  63. Don’t allow exceptions to propagate across module boundaries. 114
  64. Use sufficiently portable types in a module’s interface. 116
  65. Blend static and dynamic polymorphism judiciously. 120
  66. Customize intentionally and explicitly. 122
  67. Don’t specialize function templates. 126
  68. Don’t write unintentionally nongeneric code. 128
  69. Assert liberally to document internal assumptions and invariants. 130
  70. Establish a rational error handling policy, and follow it strictly. 132
  71. Distinguish between errors and non-errors. 134
  72. Design and write error-safe code. 137
  73. Prefer to use exceptions to report errors. 140
  74. Throw by value, catch by reference. 144
  75. Report, handle, and translate errors appropriately. 145
  76. Avoid exception specifications. 146
  77. Use vector by default. Otherwise, choose an appropriate container. 150
  78. Use vector and string instead of arrays. 152
  79. Use vector (and string::c_str) to exchange data with non-C++ APIs. 153
  80. Store only values and smart pointers in containers. 154
  81. Prefer push_back to other ways of expanding a sequence. 155
  82. Prefer range operations to single-element operations. 156
  83. Use the accepted idioms to really shrink capacity and really erase elements. 157
  84. Use a checked STL implementation. 160
  85. Prefer algorithm calls to handwritten loops. 162
  86. Use the right STL search algorithm. 165
  87. Use the right STL sort algorithm. 166
  88. Make predicates pure functions. 168
  89. Prefer function objects over functions as algorithm and comparer arguments. 170
  90. Write function objects correctly. 172
  91. Avoid type switching; prefer polymorphism. 174
  92. Rely on types, not on representations. 176
  93. Avoid using reinterpret_cast. 177
  94. Avoid using static_cast on pointers. 178
  95. Avoid casting away const. 179
  96. Don’t use C-style casts. 180
  97. Don’t memcpy or memcmp non-PODs. 182
  98. Don’t use unions to reinterpret representation. 183
  99. Don’t use varargs (ellipsis). 184
  100. Don’t use invalid objects. Don’t use unsafe functions. 185
  101. Don’t treat arrays polymorphically. 186