View C++ as a federation of languages

In the beginning, C++ was just C with some object-oriented features tacked on. Even C++'s original name, "C with Classes," reflected this simple heritage.

Today's C++, is a multiparadigm programming language, one supporting a combination of procedural, object-oriented, functional, generic, and metaprogramming features. All the "proper usage" rules seem to have exceptions.

The easiest way is to view C++ not as a single language but as a federation of related lanuages. Within a particular sublanguage, the rules tend to be simple, straightforward, and easy to remember. When you move from one sublanguage to another, however, the rules may change. To make sense of C++, you have to recognize its primary sublanguages. Fortunately, there are only four:

  • C. Way down deep, C++ is still based on C. When you find yourself working with C part of C++, the rules for effective programming reflect C's more limited scope: no templates, no exceptions, no overloading, etc.

  • Object-Oriented C++. This part of C++ is what C with Classes was all about: classes (including constructors and destructors), encapsulation, inheritance, polymorphism, virtual functions (dynamic binding). etc. This is the part of C++ to which the classic rules for object-oriented design directly apply.

  • Template C++. This is the generic programming part of C++. In fact, templates are so powerful, they give rise to a complete new programming paradigm, template metaprogramming (TMP).

  • The STL. The STL is a special template library.

Effective programming requires that you change strategy when you switch from one sublanguage to another. For example, pass-by-value is generally more efficient than pass-by-reference for built-in (C-like) types, but when you move from the C part of C++ to Object-Oriented C++, the existence of user defined constructors and destructors means that pass-by-reference-to-const is usually better. This is especially the case when working within Template C++, because there, you don't even know the type of object you're dealing with. When you cross into the STL, however, you know that iterators and fuction objects are modeled on pointers in C, so for iterators and function objects in the STL, the old C pass-by-value rule applies again.

Rules for effective C++ programming vary, depending on the part of C++ you are using.