Tech

Classes: A Deeper Look, Part 1–STRUCTURED PROGRAMMING Course Notes

Classes: A Deeper Look, Part 1

Time Class Case Study

  • Preprocessor directives (a.k.a. “preprocessor wrappers”)–Use preprocessor directives to form preprocessor wrappers.
  • Ex:
    • //prevent multiple inclusions of header file
      • #ifndef TIME_H
      • #define TIME_H
      • #endif
  • Preprocessor directives#ifndef‘ (“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.
    • Tip: Use the name of the header file in upper case with the period replaced by an underscore in the #ifndef and #define preprocessor directives of a header file.
  • Data members cannot be initialized where they’re declared in the class body (except for a class’s ‘static const‘ data members of integral or ‘enum‘ types). Initialize these data members in 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.
  • 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 can include objects of other-classes as members or they may be derived from other classes that provide attributes & behaviors the new classes can use.

Class Scope & Accessing Class Members

  • A class’s data members (attributes) & member functions (behaviors) belong to that class’s scope.
  • Nonmember functions are defined at global namespace scope.
  • Within a class’s scope, class members are immediately accessible by all of that class’s member functions & can be referenced by name.
  • Outside a class’s scope, class members are referenced through one of the handles on an object–an 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 local 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 local 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.

Separating Interface from Implementation

  • Header files contain some portions of a class’s implementation & hints about others. Inline member functions, for example, should 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.

Access Functions & Utility Functions

  • A utility 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.

‘Time’ Class Case Study: Constructors with Default Arguments

  • Like other functions, constructors can specify default arguments.

Destructors

  • 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 release an object’s storage–it 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 you do not explicitly provide a destructor, the compiler creates an “empty” destructor, so every class has exactly one destructor.

When Constructors & Destructors Are Called

  • The order in which constructors & destructors are called, depends on the order in which execution enters & 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.

‘Time’ Class Case Study: A Subtle Trap–Returning a Reference to a ‘private’ Data Member

  • 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.
  • If the function returns a ‘const‘ reference, then the reference cannot be used as a modifiable lvalue.

Default Memberwise Assignment

  • 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 assignment.
    • Memberwise assignment-each data member (attribute) of the object on the right of the assignment operator is assigned individually to the same data member in the object on the left of the assignment operator.
  • Objects may be passed by value to, or returned by value from, functions. C++ creates a new object and uses a copy constructor to copy the original object’s values into the new object.
  • 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.