Construction, Destruction, and Copying
Team LiB
Previous Section Next Section

Construction, Destruction, and Copying

47. Define and initialize member variables in the same order.

Agree with your compiler: Member variables are always initialized in the order they are declared in the class definition; the order in which you write them in the constructor initialization list is ignored. Make sure the constructor code doesn't confusingly specify a different order.

48. Prefer initialization to assignment in constructors.

Set once, use everywhere: In constructors, using initialization instead of assignment to set member variables prevents needless run-time work and takes the same amount of typing.

49. Avoid calling virtual functions in constructors and destructors.

Virtual functions only "virtually" always behave virtually: Inside constructors and destructors, they don't. Worse, any direct or indirect call to an unimplemented pure virtual function from a constructor or destructor results in undefined behavior. If your design wants virtual dispatch into a derived class from a base class constructor or destructor, you need other techniques such as post-constructors.

50. Make base class destructors public and virtual, or protected and nonvirtual.

To delete, or not to delete; that is the question: If deletion through a pointer to a base Base should be allowed, then Base's destructor must be public and virtual. Otherwise, it should be protected and nonvirtual.

51. Destructors, deallocation, and swap never fail.

Everything they attempt shall succeed: Never allow an error to be reported from a destructor, a resource deallocation function (e.g., operator delete), or a swap function. Specifically, types whose destructors may throw an exception are flatly forbidden from use with the C++ standard library.

52. Copy and destroy consistently.

What you create, also clean up: If you define any of the copy constructor, copy assignment operator, or destructor, you might need to define one or both of the others.

53. Explicitly enable or disable copying.

Copy consciously: Knowingly choose among using the compiler-generated copy constructor and assignment operator, writing your own versions, or explicitly disabling both if copying should not be allowed.

54. Avoid slicing. Consider Clone instead of copying in base classes.

Sliced bread is good; sliced objects aren't: Object slicing is automatic, invisible, and likely to bring wonderful polymorphic designs to a screeching halt. In base classes, consider disabling the copy constructor and copy assignment operator, and instead supplying a virtual Clone member function if clients need to make polymorphic (complete, deep) copies.

55. Prefer the canonical form of assignment.

Your assignment: When implementing operator=, prefer the canonical formnonvirtual and with a specific signature.

56. Whenever it makes sense, provide a no-fail swap (and provide it correctly).

swap is both a lightweight and a workhorse: Consider providing a swap function to efficiently and infallibly swap the internals of this object with another's. Such a function can be handy for implementing a number of idioms, from smoothly moving objects around to implementing assignment easily to providing a guaranteed commit function that enables strongly error-safe calling code. (See alsoItem 51.)

    Team LiB
    Previous Section Next Section