C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 27:
[27.10] Are there any lint-like guidelines for C++?

Yes, there are some practices which are generally considered dangerous. However none of these are universally "bad," since situations arise when even the worst of these is needed:

  • A class Fred's assignment operator should return *this as a Fred& (allows chaining of assignments)
  • A class with any virtual functions ought to have a virtual destructor
  • A class with any of {destructor, assignment operator, copy constructor} generally needs all 3
  • A class Fred's copy constructor and assignment operator should have const in the parameter: respectively Fred::Fred(Fred const&) and Fred& Fred::operator= (Fred const&)
  • When initializing an object's member objects in the constructor, always use initialization lists rather than assignment. The performance difference for user-defined classes can be substantial (3x!)
  • Assignment operators should make sure that self assignment does nothing, otherwise you may have a disaster. In some cases, this may require you to add an explicit test to your assignment operators.
  • When you overload operators, abide by the guidelines. For example, in classes that define both += and +, a += b and a = a + b should generally do the same thing; ditto for the other identities of built-in/intrinsic types (e.g., a += 1 and ++a; p[i] and *(p+i); etc). This can be enforced by writing the binary operations using the op= forms. E.g.,
    Fred operator+ (Fred const& a, Fred const& b)
    {
      Fred ans = a;
      ans += b;
      return ans;
    }
    
    This way the "constructive" binary operators don't even need to be friends. But it is sometimes possible to more efficiently implement common operations (e.g., if class Fred is actually std::string, and += has to reallocate/copy string memory, it may be better to know the eventual length from the beginning).