The preprocessor directives #ifndef (which means "if not defined") and #endif are used to prevent multiple inclusions of a header file. If the code between these directives has not previously been included in an application, #define defines a name that can be used to prevent future inclusions, and the code is included in the source code file.
Data members of a class cannot be initialized where they are declared in the class body (except for a class's static const data members of integral or enum types as you'll see in Chapter 10). It is strongly recommended that these data members be initialized by the class's constructor (as there is no default initialization for data members of fundamental types).
Stream manipulator setfill specifies the fill character that is displayed when an integer is output in a field that is wider than the number of digits in the value.
By default, the fill characters appear before the digits in the number.
Stream manipulator setfill is a "sticky" setting, meaning that once the fill character is set, it applies for all subsequent fields being printed.
Even though a member function declared in a class definition may be defined outside that class definition (and "tied" to the class via the binary scope resolution operator), that member function is still within that class's scope; i.e., its name is known only to other members of the class unless referred to via an object of the class, a reference to an object of the class or a pointer to an object of the class.
If a member function is defined in the body of a class definition, the C++ compiler attempts to inline calls to the member function.
Classes do not have to be created "from scratch." Rather, they can include objects of other classes as members or they may be derived from other classes that provide attributes and behaviors the new classes can use. Including class objects as members of other classes is called composition.
A class's data members and member functions belong to that class's scope.
Nonmember functions are defined at file scope.
Within a class's scope, class members are immediately accessible by all of that class's member functions and can be referenced by name.
Outside a class's scope, class members are referenced through one of the handles on an objectan object name, a reference to an object or a pointer to an object.
Member functions of a class can be overloaded, but only by other member functions of that class.
To overload a member function, provide in the class definition a prototype for each version of the overloaded function, and provide a separate definition for each version of the function.
Variables declared in a member function have block scope and are known only to that function.
If a member function defines a variable with the same name as a variable with class scope, the class-scope variable is hidden by the block-scope variable in the block scope.
The dot member selection operator (.) is preceded by an object's name or by a reference to an object to access the object's public members.
The arrow member selection operator (->) is preceded by a pointer to an object to access that object's public members.
Header files do contain some portions of the implementation and hints about others. Inline member functions, for example, need to be in a header file, so that when the compiler compiles a client, the client can include the inline function definition in place.
A class's private members that are listed in the class definition in the header file are visible to clients, even though the clients may not access the private members.
A utility function (also called a helper function) is a private member function that supports the operation of the class's public member functions. Utility functions are not intended to be used by clients of a class (but can be used by friends of a class).
Like other functions, constructors can specify default arguments.
A class's destructor is called implicitly when an object of the class is destroyed.
The name of the destructor for a class is the tilde (~) character followed by the class name.
A destructor does not actually release an object's storageit performs termination housekeeping before the system reclaims an object's memory, so the memory may be reused to hold new objects.
A destructor receives no parameters and returns no value. A class may have only one destructor.
If the programmer does not explicitly provide a destructor, the compiler creates an "empty" destructor, so every class has exactly one destructor.
The order in which constructors and destructors are called depends on the order in which execution enters and leaves the scopes where the objects are instantiated.
Generally, destructor calls are made in the reverse order of the corresponding constructor calls, but the storage classes of objects can alter the order in which destructors are called.
A reference to an object is an alias for the name of the object and, hence, may be used on the left side of an assignment statement. In this context, the reference makes a perfectly acceptable lvalue that can receive a value. One way to use this capability (unfortunately!) is to have a public member function of a class return a reference to a private data member of that class. If the function returns a const reference, then the reference cannot be used as a modifiable lvalue.
The assignment operator (=) can be used to assign an object to another object of the same type. By default, such assignment is performed by memberwise assignmenteach member of the object on the right of the assignment operator is assigned individually to the same member in the object on the left of the assignment operator.
Objects may be passed as function arguments and may be returned from functions. Such passing and returning is performed using pass-by-value by defaulta copy of the object is passed or returned. In such cases, C++ creates a new object and uses a copy constructor to copy the original object's values into the new object. We explain these in detail in Chapter 11, Operator Overloading; String and Array Objects.
For each class, the compiler provides a default copy constructor that copies each member of the original object into the corresponding member of the new object.
Many substantial class libraries exist, and others are being developed worldwide.
Software reusability speeds the development of powerful, high-quality software. Rapid applications development (RAD) through the mechanisms of reusable componentry has become an important field.