Summary

Section 9.2 Time Class Case Study: Separating Interface from Implementation

  • Placing a complete class definition in a header reveals the entire implementation of the class to the class’s clients—a header is simply a text file that anyone can open and read.

  • Conventional software engineering wisdom says that to use an object of a class, the client code needs to know only: what member functions to call, what arguments to provide to each member function and what return type to expect from each member function. The client code does not need to know how those functions are implemented.

Section 9.2.1 Interface of a Class

  • Interfaces (p. 388) define and standardize the ways in which things such as people and systems interact with one another.

  • The interface of a class describes what services a class’s clients can use and how to request those services, but not how the class carries out the services.

  • A class’s public interface consists of the class’s public member functions (also known as the class’s public services).

  • You can specify a class’s interface by writing a class definition that lists only the class’s member-function prototypes and the class’s data members.

Section 9.2.2 Separating the Interface from the Implementation

  • To separate the class’s interface from its implementation, we break up the class into two files— a header in which the class is defined and a source-code file in which the class’s member functions are defined.

  • By convention, member-function definitions are placed in a source-code file of the same base name as the class’s header but with a .cpp filename extension (some compilers support other filename extensions as well).

Section 9.2.3 Time Class Definition

  • A class definition that contains function prototypes rather than definitions describes the class’s public interface without revealing the class’s member-function implementations.

  • The class’s header still specifies the class’s private data members as well—the compiler must know the data members of the class to determine how much memory to reserve for each object of the class.

  • Including the class’s header in the client code provides the compiler with the information it needs to ensure that the client code calls the class’s member functions correctly.

  • An include guard (p. 389)—consisting of #ifndef, #define and #endif—prevents a header from being #included multiple times in the same source-code file.

  • Attempts to include a header multiple times (inadvertently) typically occur in large programs with many headers that may themselves include other headers.

Section 9.2.5 Scope Resolution Operator (::)

  • When member functions are defined outside a class’s definition, each member function’s name must be preceded by the class name and the scope resolution operator (::). This “ties” each member function to the class definition, which declares the class’s members, telling the compiler that each member function is within that class’s scope (p. 391).

Section 9.2.6 Including the Class Header in the Source-Code File

  • The source-code file containing a class’s member-function definitions must include the class’s header. This enables the compiler to ensure that the first line of each member function matches its prototype in the class’s header and that each member function knows about the class’s data members and other member functions.

Section 9.2.7 Time Class Member Function setTime and Throwing Exceptions

  • A function can throw an exception (p. 392) of type invalid_argument (p. 392) to notify the client code that an invalid argument was received.

  • A throw statement (p. 392) creates and throws an object of the type specified to the right of the throw keyword.

  • After an exception object is created, the throw statement immediately terminates the function and the exception is returned to the calling function.

Section 9.2.8 Time Class Member Function toUniversalString and String Stream Processing

  • Objects of class ostringstream (p. 392; from the header <sstream>) provide the same functionality as cout, but write their output to string objects in memory.

  • Class ostringstream’s str (p. 392) member function returns the string created by an ostring-stream.

  • Parameterized stream manipulator setfill (p. 392) specifies the fill character (p. 392) that’s displayed when an integer is output in a field wider than the number of digits in the value.

  • The fill characters appear to the left of the digits in the number for a right-aligned value—for left aligned values, the fill characters appear to the right.

  • Once the fill character is specified with setfill, it applies for all subsequent values that are displayed in fields wider than the value being displayed—this is a sticky setting.

Section 9.2.10 Implicitly Inlining Member Functions

  • A member function defined in a class’s body is implicitly declared inline.

Section 9.2.11 Member Functions vs. Global Functions

  • Classes often contain member functions that take no arguments, because these member functions implicitly know the data members for the particular object on which they’re invoked. This can make member-function calls more concise and less error prone than conventional function calls in procedural programming.

Section 9.2.12 Using Class Time

  • Once a class is defined, it can be used as a type in declarations of objects, references and pointers.

Section 9.2.13 Object Size

  • People new to object-oriented programming often suppose that objects must be quite large because they contain data members and member functions. Logically, this is true; physically, however, this is not the case—member functions are stored separately from the objects of a class.

Section 9.3 Compilation and Linking Process

  • Often a class’s interface and implementation will be created and compiled by one programmer and used by a separate programmer who implements the client code that uses the class.

  • A class-implementation programmer responsible for creating a reusable class creates the header and the source-code file that #includes the header, then compiles the source-code file to create the class’s object code.

  • To hide the class’s member-function implementation details, the class-implementation programmer would provide the client-code programmer with the class’s header (which specifies the class’s interface and data members) and the class’s object code (i.e., the machine-code instructions that represent the class’s member functions).

  • The client-code programmer is not given the source-code file with the class’s member function definitions, so the client remains unaware of how the class’s member functions are implemented.

  • The client-code programmer needs to know only the class’s interface to use the class and must be able to link its object code. Since the interface of the class is part of the class definition in the class’s header, the client-code programmer must have access to this file and must #include it in the client’s source-code file.

  • To create the executable application, the last step is to link the object code for the client code, the object code for the member-function implementations of the class(es) used by the client code and the C++ Standard Library object code used by the class-implementation programmer and the client-code programmer.

  • The linker’s output is the executable application. Compilers and IDEs typically invoke the linker for you after compiling your code.

Section 9.4 Class Scope and Accessing Class Members

  • A class’s data members and member functions 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 non-static functions and 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.

  • Variables declared in a member function have block scope and are known only to that function.

  • 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 (->; p. 398) is preceded by a pointer to an object to access that object’s public members.

Section 9.5 Access Functions and Utility Functions

  • Access functions (p. 399) read or display data. They can also be used to test the truth or falsity of conditions—such functions are often called predicate functions.

  • A utility function (p. 399) 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.

Section 9.6.1 Constructors with Default Arguments

  • Like other functions, constructors can specify default arguments.

Section 9.6.2 Overloaded Constructors and C++11 Delegating Constructors

  • To overload a constructor, provide in the class definition a prototype for each version of the constructor, and provide a separate constructor definition for each overloaded version. This also applies to the class’s member functions.

  • Just as a constructor can call a class’s other member functions to perform tasks, C++11 allows constructors to call other constructors in the same class. To do so, you use a member initializer with the name of the class.

  • The calling constructor is known as a delegating constructor (p. 405)—it delegates its work to another constructor. This is useful when overloaded constructors have common code that previously would have been defined in a private utility function and called by all the constructors.

Section 9.7 Destructors

  • A class’s destructor (p. 405) 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 (p. 405) 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.

Section 9.8 When Constructors and Destructors Are Called

  • 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 global and local static objects’ destructors are called after all non-static local objects are destroyed.

  • Function exit forces a program to terminate immediately and does not execute the destructors of local objects. exit often is used to terminate a program when a fatal unrecoverable error occurs.

  • Function abort forces the program to terminate immediately, without allowing programmer-defined cleanup code of any kind to be called. abort is usually used to indicate an abnormal termination of the program.

Section 9.9 Time Class Case Study: A Subtle Trap—Returning a Reference or a Pointer 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 reference to const data, then the reference cannot be used as a modifiable lvalue.

Section 9.10 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 (p. 411).

  • Objects may be passed by value to or returned by value from functions. C++ creates a new object and uses a copy constructor (p. 413) 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.

Section 9.11 const Objects and const Member Functions

  • The keyword const can be used to specify that an object is not modifiable and that any attempt to modify the object should result in a compilation error.

  • C++ compilers disallow non-const member function calls on const objects.

  • An attempt by a const member function to modify an object of its class is a compilation error.

  • A member function is specified as const both in its prototype and in its definition.

  • A const object must be initialized.

  • Constructors and destructors cannot be declared const.

Section 9.12 Composition: Objects as Members of Classes

  • A class can have objects of other classes as members—this concept is called composition.

  • Member objects are constructed in the order in which they’re declared in the class definition and before their enclosing class objects are constructed.

  • If a member initializer is not provided for a member object, the member object’s default constructor will be called implicitly.

Section 9.13 friend Functions and friend Classes

  • A friend function (p. 421) of a class is defined outside that class’s scope, yet has the right to access all of the class’s members. Standalone functions or entire classes may be declared to be friends.

  • A friend declaration can appear anywhere in the class.

  • The friendship relation is neither symmetric nor transitive.

Section 9.14 Using the this Pointer

  • Every object has access to its own address through the this pointer (p. 423).

  • An object’s this pointer is not part of the object itself—i.e., the size of the memory occupied by the this pointer is not reflected in the result of a sizeof operation on the object.

  • The this pointer is passed as an implicit argument to each non-static member function.

  • Objects use the this pointer implicitly (as we’ve done to this point) or explicitly to reference their data members and member functions.

  • The this pointer enables cascaded member-function calls (p. 425) in which multiple functions are invoked in the same statement.

Section 9.15 static Class Members

  • A static data member (p. 429) represents “classwide” information (i.e., a property of the class shared by all instances, not a property of a specific object of the class).

  • static data members have class scope and can be declared public, private or protected.

  • A class’s static members exist even when no objects of that class exist.

  • To access a public static class member when no objects of the class exist, simply prefix the class name and the scope resolution operator (::) to the name of the data member.

  • The static keyword cannot be applied to a member definition that appears outside the class definition.

  • A member function should be declared static (p. 430) if it does not access non-static data members or non-static member functions of the class. Unlike non-static member functions, a static member function does not have a this pointer, because static data members and static member functions exist independently of any objects of a class.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset