This document provides an overview of topics covered in a C++ programming course, including: - Introduction to C++ language fundamentals like data types, variables, operators, control structures, functions, and classes - Memory concepts, arithmetic, decision making, and algorithms - Structured and object-oriented programming principles - The basics of the C++ environment like compilers, linkers, and input/output streams - Common library functions and concepts like headers, prototypes, and enumerations The document serves as an introductory reference for anyone learning C++ or wanting to understand the basic building blocks of the language.
An introduction to C++ programming explaining computer languages, history of C and C++.
C++ programming concepts including structured/OOP programming, environment setup, input/output functions.
Introduction to basic data operations including arithmetic operations, control structures, and decision making.
Explains control structures (if, while, switch) and logical operations used in decision making.
Introduction to functions, including function definitions, parameters, and exception handling basics.
Explains recursion through examples and introduces function templates for generic programming.
Introduces pointers, including pointer operations and dynamic memory management with new and delete.
C++ class concepts, including constructors, destructors, inheritance types (single/multiple).
Explains polymorphism in programming, virtual functions, and inheritance relationships.
Introduction to function and class templates, emphasizing the use of STL for containers and algorithms. Demonstrates handling file operations for creating, reading, and updating sequential access files.
Introduction to exceptions, handling exceptions, and creating custom exception classes.
Introduction to UML, its diagrams, and usage in modeling object-oriented systems.
Topics for C++Language 1.Introduction to C++ language 2.Structured/OO Programming 3.Memory Concepts 4.Arithmetic 5.Control Structure 6.Functions 7.Arrays 8.Pointers 9.Structures 10.Inheritance 11.Polymorphism 12.Multiple Inheritance 13.Templetes 14.Stacks/Queue 15.Exception Handling 16.Preprocessing 17.Unified Modeling Language
3.
Introduction to C++language Course Description An introduction to the development of programs using C++. Emphasis is given to the development of program modules that can function independently. Object-oriented design The theory of data structures and programming language design is continued. Course Information
4.
Computer Languages Machinelanguage Generally consist of strings of numbers - Ultimately 0s and 1s - Machine-dependent Example: +1300042774 +1400593419 Assembly language English-like abbreviations for elementary operations Incomprehensible to computers - Convert to machine language Example: LOAD BASEPAY ADD OVERPAY STORE GROSSPAY High-level languages Similar to everyday English, use common mathematical notations Compiler/Interpreter Example: grossPay = basePay + overTimePay
5.
History of Cand C++ History of C Evolved from two other programming languages BCPL and B: “Typeless” languages Dennis Ritchie (Bell Lab): Added typing, other features 1989: ANSI standard/ ANSI/ISO 9899: 1990 History of C++ Early 1980s: Bjarne Stroustrup (Bell Lab) Provides capabilities for object-oriented programming Objects: reusable software components Object-oriented programs Building block approach” to creating programs C++ programs are built from pieces called classes and functions C++ standard library: Rich collections of existing classes and functions
6.
Structured/OO Programming Structuredprogramming (1960s) Disciplined approach to writing programs Clear, easy to test and debug, and easy to modify E.g.Pascal:1971: Niklaus Wirth OOP “Software reuse” “Modularity” “Extensible” More understandable, better organized and easier to maintain than procedural programming
7.
Basics of aTypical C++ Environment C++ systems Program-development environment Language C++ Standard Library C++ program names extensions .cpp .cxx .cc .C
8.
Basics of aTypical C++ Environment Phases of C++ Programs: 1. Edit 2. Preprocess 3. Compile 4. Link 5. Load 6. Execute Loader Primary Memory Program is created in the editor and stored on disk. Preprocessor program processes the code. Loader puts program in memory. CPU takes each instruction and executes it, possibly storing new data values as the program executes. Compiler Compiler creates object code and stores it on disk. Linker links the object code with the libraries, creates an executable file and stores it on disk Editor Preprocessor Linker CPU Primary Memory . . . . . . . . . . . . Disk Disk Disk Disk Disk
9.
Basics of aTypical C++ Environment Common Input/output functions cin Standard input stream Normally keyboard cout Standard output stream Normally computer screen cerr Standard error stream Display error messages Comments: C’s comment /* .. */ OR Begin with // or Preprocessor directives: Begin with # Processed before compiling
10.
A Simple Program:Printing a Line of Text Standard output stream object std::cout “Connected” to screen << Stream insertion operator Value to right (right operand) inserted into output stream Namespace std:: specifies that entity belongs to “namespace” std std:: removed through use of using statements Escape characters: Indicates “special” character output
11.
1 // Example1 2 // A first program in C++. 3 #include <iostream> 4 5 // function main begins program execution 6 int main() 7 { 8 std::cout << "Welcome to C++!n"; 9 10 return 0; // indicate that program ended successfully 11 12 } // end function main Welcome to C++!
12.
A Simple Program:Printing a Line of Text Escape Sequence Description n Newline. Position the screen cursor to the beginning of the next line. t Horizontal tab. Move the screen cursor to the next tab stop. r Carriage return. Position the screen cursor to the beginning of the current line; do not advance to the next line. a Alert. Sound the system bell. Backslash. Used to print a backslash character. " Double quote. Used to print a double quote character.
13.
Memory Concepts Variablenames Correspond to actual locations in computer's memory Every variable has name, type, size and value When new value placed into variable, overwrites previous value std::cin >> integer1; Assume user entered 45 std::cin >> integer2; Assume user entered 72 sum = integer1 + integer2; integer1 45 integer1 45 integer2 72 integer1 45 integer2 72 sum 117
14.
Arithmetic Arithmetic calculations * : Multiplication / : Division Integer division truncates remainder 7 / 5 evaluates to 1 % : Modulus operator returns remainder 7 % 5 evaluates to 2 Operator(s) Operation(s) Order of evaluation (precedence) () Parentheses Evaluated first. If the parentheses are nested, the expression in the innermost pair is evaluated first. If there are several pairs of parentheses “on the same level” (i.e., not nested), they are evaluated left to right. *, /, or % Multiplication Division Modulus Evaluated second. If there are several, they re evaluated left to right. + or - Addition Subtraction Evaluated last. If there are several, they are evaluated left to right.
15.
Decision Making: Equalityand Relational Operators if structure Make decision based on truth or falsity of condition If condition met, body executed Else, body not executed Equality and relational operators Equality operators Same level of precedence Relational operators Same level of precedence Associate left to right
16.
Decision Making: Equalityand Relational Operators Standard algebraic equality operator or relational operator C++ equality or relational operator Example of C++ condition Meaning of C++ condition Relational operators > > x > y x is greater than y < < x < y x is less than y >= x >= y x is greater than or equal to y <= x <= y x is less than or equal to y Equality operators = == x == y x is equal to y != x != y x is not equal to y
17.
Algorithms /pseudocode Computingproblems Solved by executing a series of actions in a specific order Algorithm: a procedure determining Actions to be executed Order to be executed Example: recipe Program control Specifies the order in which statements are executed Pseudocode Artificial, informal language used to develop algorithms Similar to everyday English
18.
Control Structures Sequentialexecution Statements executed in order Transfer of control Next statement executed not next one in sequence Structured programming – “goto”-less programming 3 control structures to build any program Sequence structure Programs executed sequentially by default Selection structures if, if/else, switch Repetition structures while, do/while, for
19.
Keywords C++ keywords Cannot be used as identifiers or variable names C++ Keywords Keywords common to the C and C++ programming languages auto break case char const continue default do double else enum extern float for goto if int long register return short signed sizeof static struct switch typedef union unsigned void volatile while C++ only keywords asm bool catch class const_cast delete dynamic_cast explicit false friend inline mutable namespace new operator private protected public reinterpret_cast static_cast template this throw true try typeid typename using virtual wchar_t
20.
Control Structures Flowchart Graphical representation of an algorithm Special-purpose symbols connected by arrows (flowlines) Rectangle symbol (action symbol) Any type of action Oval symbol Beginning or end of a program, or a section of code (circles) Exercise: Find greater of three numbers
21.
if/else Selection Structure Ternary conditional operator (?:) Three arguments (condition, value if true, value if false) Code could be written: cout << ( grade >= 60 ? “Passed” : “Failed” ); truefalse print “Failed” print “Passed” grade >= 60 Condition Value if true Value if false
22.
while Repetition Structure Repetition structure Counter-controlled While/do while loop: repeated until condition becomes false For: loop repeated until counter reaches certain value Flowchart representation? Sentinel value Indicates “end of data entry” Sentinel chosen so it cannot be confused with regular input Example int product = 2; while ( product <= 1000 ) { product = 2 * product; cout << product; } Flowchart representation? What is the output?
23.
switch Multiple-Selection Structure switch Test variable for multiple values Series of case labels and optional default case switch ( variable ) { case value1: // taken if variable == value1 statements break; // necessary to exit switch case value2: case value3: // taken if variable == value2 or == value3 statements break; default: // taken if none matches statements break; }
24.
break and continueStatements break statement Immediate exit from while, for, do/while, switch Program continues with first statement after structure Common uses Escape early from a loop Skip the remainder of switch
25.
Logical Operators Usedas conditions in loops, if statements && (logical AND) true if both conditions are true if ( gender == 1 && age >= 65 ) ++seniorFemales; || (logical OR) true if either of condition is true if ( semesterAverage >= 90 || finalExam >= 90 ) cout << "Student grade is A" << endl;
26.
Logical Operators !(logical NOT, logical negation) Returns true when its condition is false, & vice versa if ( !( grade == sentinelValue ) ) cout << "The next grade is " << grade << endl; Alternative: if ( grade != sentinelValue ) cout << "The next grade is " << grade << endl;
27.
Confusing Equality (==)and Assignment (=) Operators Common error Does not typically cause syntax errors Aspects of problem Expressions that have a value can be used for decision Zero = false, nonzero = true Assignment statements produce a value (the value to be assigned) if == was replaced with = if ( payCode = 4 ) cout << "You get a bonus!" << endl; What happens?
28.
Confusing Equality (==)and Assignment (=) Operators Lvalues Expressions that can appear on left side of equation Can be changed x = 4; Rvalues Only appear on right side of equation Constants, such as numbers (i.e. cannot write 4 = x;) Lvalues can be used as rvalues, but not vice versa
29.
Structured-Programming Summary Structuredprogramming Programs easier to understand, test, debug and modify Rules for structured programming Only use single-entry/single-exit control structures Rules 1) Begin with the “simplest flowchart” 2) Any rectangle (action) can be replaced by two rectangles (actions) in sequence 3) Any rectangle (action) can be replaced by any control structure (sequence, if, if/else, switch, while, do/while or for) 4) Rules 2 and 3 can be applied in any order and multiple times
Program Components inC++ Modules: functions and classes Programs use new and “prepackaged” modules New: programmer-defined functions, classes Prepackaged: from the standard library Functions invoked by function call Function name and information (arguments) it needs Function definitions Only written once Hidden from other functions
32.
Functions Functions Modularizea program Software reusability Call function multiple times Local variables Known only in the function in which they are defined All variables declared in function definitions are local variables Parameters Local variables passed to function when called Provide outside information
33.
Math Library Functions Performcommon mathematical calculations Include the header file <cmath> Functions called by writing functionName (argument); or functionName (argument1, argument2, …); Example cout << sqrt( 900.0 ); All functions in math library return a double Function arguments can be Constants: sqrt( 4 ); Variables: sqrt( x ); Expressions: sqrt( sqrt( x ) ) ; sqrt( 3 - 6x ); Other functions ceil(x), floor(x), log10(x), etc.
34.
Function Definitions Function prototype intsquare( int ); Calling/invoking a function square(x); Format for function definition return-value-type function-name( parameter-list ) { declarations and statements } Prototype must match function definition Function prototype double maximum( double, double, double ); Definition double maximum( double x, double y, double z ) { … }
35.
Function Definitions Examplefunction int square( int y ) { return y * y; } return keyword Returns data, and control goes to function’s caller If no data to return, use return; Function ends when reaches right brace Control goes to caller Functions cannot be defined inside other functions
36.
Function Prototypes Functionsignature Part of prototype with name and parameters double maximum( double, double, double ); Argument Coercion Force arguments to be of proper type Converting int (4) to double (4.0) cout << sqrt(4) Conversion rules Arguments usually converted automatically Changing from double to int can truncate data 3.4 to 3 Mixed type goes to highest type (promotion) Function signature
37.
Function Prototypes Data types longdouble double float unsigned long int (synonymous with unsigned long) long int (synonymous with long) unsigned int (synonymous with unsigned) int unsigned short int (synonymous with unsigned short) short int (synonymous with short) unsigned char char bool (false becomes 0, true becomes 1) Fig. 3.5 Promotion hierarc hy for built-in data types.
38.
Header Files Headerfiles contain Function prototypes Definitions of data types and constants Header files ending with .h Programmer-defined header files #include “myheader.h” Library header files #include <cmath>
39.
Enumeration: enum Enumeration Set of integers with identifiers enum typeName {constant1, constant2…}; Constants start at 0 (default), incremented by 1 Constants need unique names Cannot assign integer to enumeration variable Must use a previously defined enumeration type Example enum Status {CONTINUE, WON, LOST}; Status enumVar; enumVar = WON; // cannot do enumVar = 1
40.
Storage Classes Variableshave attributes Have seen name, type, size, value Storage class How long variable exists in memory Scope Where variable can be referenced in program Linkage For multiple-file program which files can use it
41.
Storage Classes Automaticstorage class Variable created when program enters its block Variable destroyed when program leaves block Only local variables of functions can be automatic Automatic by default keyword auto explicitly declares automatic register keyword Hint to place variable in high-speed register Good for often-used items (loop counters) Often unnecessary, compiler optimizes Specify either register or auto, not both register int counter = 1;
42.
Storage Classes Staticstorage class Variables exist for entire program For functions, name exists for entire program May not be accessible, scope rules still apply auto and register keyword local variables in function register variables are kept in CPU registers static keyword Local variables in function Keeps value between function calls Only known in own function extern keyword Default for global variables/functions Globals: defined outside of a function block Known in any function that comes after it
43.
Scope Rules Scope Portion of program where identifier can be used File scope Defined outside a function, known in all functions Global variables, function definitions and prototypes Function scope Can only be referenced inside defining function Only labels, e.g., identifiers with a colon (case:)
44.
Scope Rules Blockscope Begins at declaration, ends at right brace } Can only be referenced in this range Local variables, function parameters Local static variables still have block scope Storage class separate from scope Function-prototype scope Parameter list of prototype Names in prototype optional Compiler ignores In a single prototype, name can be used once
45.
1 // Example2 2 // A scoping example. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 void useLocal( void ); // function prototype 9 void useStaticLocal( void ); // function prototype 10 void useGlobal( void ); // function prototype 11 12 int x = 1; // global variable 13 14 int main() 15 { 16 int x = 5; // local variable to main 17 18 cout << "local x in main's outer scope is " << x << endl; 19 20 { // start new scope 21 22 int x = 7; 23 24 cout << "local x in main's inner scope is " << x << endl; 25 26 } // end new scope Local/global? Scope? Local/global? Scope? Local/global? Scope?
46.
43 // useLocalreinitializes local variable x during each call 44 void useLocal( void ) 45 { 46 int x = 25; // initialized each time useLocal is called 47 48 cout << endl << "local x is " << x 49 << " on entering useLocal" << endl; 50 ++x; 51 cout << "local x is " << x 52 << " on exiting useLocal" << endl; 53 54 } // end function useLocal 55 Local/global? Scope?
47.
56 // useStaticLocalinitializes static local variable x only the 57 // first time the function is called; value of x is saved 58 // between calls to this function 59 void useStaticLocal( void ) 60 { 61 // initialized only first time useStaticLocal is called 62 static int x = 50; 63 64 cout << endl << "local static x is " << x 65 << " on entering useStaticLocal" << endl; 66 ++x; 67 cout << "local static x is " << x 68 << " on exiting useStaticLocal" << endl; 69 70 } // end function useStaticLocal 71 Local/global? Scope?
48.
Recursion Recursive functions Functions that call themselves Can only solve a base case If not base case Break problem into smaller problem(s) Launch new copy of function to work on the smaller problem (recursive call/recursive step) Slowly converges towards base case Function makes call to itself inside the return statement Eventually base case gets solved Answer works way back up, solves entire problem
49.
Recursion Example: factorial n!= n * ( n – 1 ) * ( n – 2 ) * … * 1 Recursive relationship ( n! = n * ( n – 1 )! ) 5! = 5 * 4! 4! = 4 * 3!… Base case (1! = 0! = 1)
50.
Example Using Recursion: FibonacciSeries Fibonacci series: 0, 1, 1, 2, 3, 5, 8... Each number sum of two previous ones Example of a recursive formula: fib(n) = fib(n-1) + fib(n-2) C++ code for Fibonacci function long fibonacci( long n ) { if ???? // base case return ???; else ??? }
51.
Example Using Recursion: FibonacciSeries Order of operations return fibonacci( n - 1 ) + fibonacci( n - 2 ); Recursive function calls Each level of recursion doubles the number of function calls 30th number = 2^30 ~ 4 billion function calls Exponential complexity f( 3 ) f( 1 )f( 2 ) f( 1 ) f( 0 ) return 1 return 1 return 0 return + +return
52.
Recursion vs. Iteration Repetition Iteration: explicit loop Recursion: repeated function calls Termination Iteration: loop condition fails Recursion: base case recognized Both can have infinite loops Balance between performance (iteration) and good software engineering (recursion)
53.
Inline Functions Inlinefunctions Keyword inline before function Asks the compiler to copy code into program instead of making function call Reduce function-call overhead Compiler can ignore inline Good for small, often-used functions Example inline double cube( const double s ) { return s * s * s; } const tells compiler that function does not modify s
54.
References and Reference Parameters Call by value Copy of data passed to function Changes to copy do not change original Prevent unwanted side effects Call by reference Function can directly access data Changes affect original Reference parameter Alias for argument in function call Passes parameter by reference Use & after data type in prototype void myFunction( int &data ) Read “data is a reference to an int” Function call format the same However, original can now be changed
55.
References and Reference Parameters Pointers Another way to pass-by-refernce References as aliases to other variables Refer to same variable Can be used within a function int count = 1; // declare integer variable count int &cRef = count; // create cRef as an alias for count ++cRef; // increment count (using its alias) References must be initialized when declared Otherwise, compiler error Dangling reference Reference to undefined variable
56.
Default Arguments Functioncall with omitted parameters If not enough parameters, rightmost go to their defaults Default values Can be constants, global variables, or function calls Set defaults in function prototype int myFunction( int x = 1, int y = 2, int z = 3 ); myFunction(3) x = 3, y and z get defaults (rightmost) myFunction(3, 5) x = 3, y = 5 and z gets default
57.
Unitary Scope Resolution Operator Unary scope resolution operator (::) Access global variable if local variable has same name Not needed if names are different Use ::variable y = ::x + 3; Good to avoid using same names for locals and globals
58.
Function Overloading Functionoverloading Functions with same name and different parameters Should perform similar tasks i.e., function to square ints and function to square floats int square( int x) {return x * x;} float square(float x) { return x * x; } Overloaded functions distinguished by signature Based on name and parameter types (order matters) Name mangling Encode function identifier with no. and types of parameters Type-safe linkage Ensures proper overloaded function called
59.
Function Templates Compactway to make overloaded functions Generate separate function for different data types Format Begin with keyword template Formal type parameters in brackets <> Every type parameter preceded by typename or class (synonyms) Placeholders for built-in types (i.e., int) or user-defined types Specify arguments types, return types, declare variables Function definition like normal, except formal types used
60.
Function Templates Example template< class T > // or template< typename T > T square( T value1 ) { return value1 * value1; } T is a formal type, used as parameter type Above function returns variable of same type as parameter In function call, T replaced by real type If int, all T's become ints int x; int y = square(x);
61.
1 // Example3 2 // Using a function template. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 // definition of function template maximum 10 template < class T > // or template < typename T > 11 T maximum( T value1, T value2, T value3 ) 12 { 13 T max = value1; 14 15 if ( value2 > max ) 16 max = value2; 17 18 if ( value3 > max ) 19 max = value3; 20 21 return max; 22 23 } // end function template maximum 24 Formal type parameter T placeholder for type of data to be tested by maximum. maximum expects all parameters to be of the same type.
62.
25 int main() 26{ 27 // demonstrate maximum with int values 28 int int1, int2, int3; 29 30 cout << "Input three integer values: "; 31 cin >> int1 >> int2 >> int3; 32 33 // invoke int version of maximum 34 cout << "The maximum integer value is: " 35 << maximum( int1, int2, int3 ); 36 37 // demonstrate maximum with double values 38 double double1, double2, double3; 39 40 cout << "nnInput three double values: "; 41 cin >> double1 >> double2 >> double3; 42 43 // invoke double version of maximum 44 cout << "The maximum double value is: " 45 << maximum( double1, double2, double3 ); 46 maximum called with various data types.
63.
47 // demonstratemaximum with char values 48 char char1, char2, char3; 49 50 cout << "nnInput three characters: "; 51 cin >> char1 >> char2 >> char3; 52 53 // invoke char version of maximum 54 cout << "The maximum character value is: " 55 << maximum( char1, char2, char3 ) 56 << endl; 57 58 return 0; // indicates successful termination 59 60 } // end main Input three integer values: 1 2 3 The maximum integer value is: 3 Input three double values: 3.3 2.2 1.1 The maximum double value is: 3.3 Input three characters: A C B The maximum character value is: C
64.
Arrays Array Consecutivegroup of memory locations Same name and type (int, char, etc.) To refer to an element Specify array name and position number (index) Format: arrayname[ position number ] First element at position 0 N-element array c c[ 0 ], c[ 1 ] … c[ n - 1 ] Nth element as position N-1
65.
Declaring Arrays Whendeclaring arrays, specify Name Type of array Any data type Number of elements type arrayName[ arraySize ]; int c[ 10 ]; // array of 10 integers float d[ 3284 ]; // array of 3284 floats Declaring multiple arrays of same type Use comma separated list, like regular variables int b[ 100 ], x[ 27 ];
66.
Examples Using Arrays Initializing arrays For loop Set each element Initializer list Specify each element when array declared int n[ 5 ] = { 1, 2, 3, 4, 5 }; If not enough initializers, rightmost elements 0 If too many, syntax error To set every element to 0 int n[ 5 ] = { 0 }; If array size omitted, initializers determine size int n[] = { 1, 2, 3, 4, 5 }; 5 initializers, therefore 5 element array static int array[3]; ??
67.
Examples Using Arrays Strings Arrays of characters All strings end with null ('0') Examples char string1[] = "hello"; Null character implicitly added string1 has 6 elements char string1[] = { 'h', 'e', 'l', 'l', 'o', '0’ }; Subscripting is the same String1[ 0 ] is 'h' string1[ 2 ] is 'l'
68.
Examples Using Arrays Input from keyboard char string2[ 10 ]; cin >> string2; Puts user input in string Stops at first whitespace character Adds null character If too much text entered, data written beyond array We want to avoid this Printing strings cout << string2 << endl; Does not work for other array types Characters printed until null found
69.
Passing Arrays toFunctions Specify name without brackets To pass array myArray to myFunction int myArray[ 24 ]; myFunction( myArray, 24 ); Array size usually passed, but not required Useful to iterate over all elements Arrays passed-by-reference Functions can modify original array data Value of name of array is address of first element Function knows where the array is stored Can change original memory locations
70.
Passing Arrays toFunctions Functions taking arrays Function prototype void modifyArray( int b[], int arraySize ); void modifyArray( int [], int ); Names optional in prototype Both take an integer array and a single integer No need for array size between brackets Ignored by compiler If declare array parameter as const Cannot be modified (compiler error) void doNotModify( const int [] );
71.
Sorting Arrays Example: Go left to right, and exchange elements as necessary One pass for each element Original: 3 4 2 7 6 Pass 1: 3 2 4 6 7 (elements exchanged) Pass 2: 2 3 4 6 7 Pass 3: 2 3 4 6 7 (no changes needed) Pass 4: 2 3 4 6 7 Pass 5: 2 3 4 6 7 Small elements "bubble" to the top (like 2 in this example)
72.
Multiple-Subscripted Arrays Multiple subscripts a[i ][ j ] Tables with rows and columns Specify row, then column “Array of arrays” a[0] is an array of 4 elements a[0][0] is the first element of that array Row 0 Row 1 Row 2 Column 0 Column 1 Column 2 Column 3 a[ 0 ][ 0 ] a[ 1 ][ 0 ] a[ 2 ][ 0 ] a[ 0 ][ 1 ] a[ 1 ][ 1 ] a[ 2 ][ 1 ] a[ 0 ][ 2 ] a[ 1 ][ 2 ] a[ 2 ][ 2 ] a[ 0 ][ 3 ] a[ 1 ][ 3 ] a[ 2 ][ 3 ] Row subscript Array name Column subscript To initialize Default of 0 Initializers grouped by row in braces int b[ 2 ][ 2 ]={ { 1, 2 }, { 3, 4 } }; int b[ 2 ][ 2 ] = { { 1 }, { 3, 4 } };
73.
Pointer Pointer variables Contain memory addresses as values Normally, variable contains specific value (direct reference) Pointers contain address of variable that has specific value (indirect reference) Indirection Referencing value through pointer Pointer declarations * indicates variable is pointer int *myPtr; declares pointer to int, pointer of type int * Multiple pointers require multiple asterisks int *myPtr1, *myPtr2; count 7 countPtr count 7 Pointer Variable Declarations and Initialization
74.
Pointer Operators &(address operator) Returns memory address of its operand Example int y = 5; int *yPtr; yPtr = &y; yPtr y 5 yptr 500000 600000 y 600000 5 address of y is value of yptr yPtr “points to” y * - indirection/ dereferencing operator) *yPtr returns y dereferenced pointer is lvalue *yptr = 9 ??
75.
Calling Functions byReference 3 ways to pass arguments to function Pass-by-value Pass-by-reference with reference arguments Pass-by-reference with pointer arguments Arguments passed to function using reference arguments Modify original values of arguments More than one value “returned” int Cube(int *x) { …} Function call: Cube(&a)
76.
Using const withPointers const qualifier Value of variable should not be modified const used when function does not need to change a variable Principle of least privilege const pointers Always point to same memory location Default for array name Must be initialized when declared Four ways to pass pointer to function Nonconstant pointer to nonconstant data Highest amount of access Nonconstant pointer to constant data Constant pointer to nonconstant data Constant pointer to constant data Least amount of access
77.
1 // Example3 2 // Attempting to modify a constant pointer to 3 // non-constant data. 4 5 int main() 6 { 7 int x, y; 8 9 // ptr is a constant pointer to an integer that can 10 // be modified through ptr, but ptr always points to the 11 // same memory location. 12 int * const ptr = &x; 13 14 *ptr = 7; // allowed: *ptr is not const 15 ptr = &y; // error: ptr is const; cannot assign new address 16 17 return 0; // indicates successful termination 18 19 } // end main d:cpphtp4_examplesch05Fig05_13.cpp(15) : error C2166: l-value specifies const object ptr is constant pointer to integer.Can modify x (pointed to by ptr) since x not constant.Cannot modify ptr to point to new address since ptr is constant. Line 15 generates compiler error by attempting to assign new address to constant pointer.
78.
1 // Example4 2 // Attempting to modify a constant pointer to constant data. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 int main() 9 { 10 int x = 5, y; 11 12 // ptr is a constant pointer to a constant integer. 13 // ptr always points to the same location; the integer 14 // at that location cannot be modified. 15 const int *const ptr = &x; 16 17 cout << *ptr << endl; 18 19 *ptr = 7; // error: *ptr is const; cannot assign new value 20 ptr = &y; // error: ptr is const; cannot assign new address 21 22 return 0; // indicates successful termination 23 24 } // end main ptr is constant pointer to integer constant. Cannot modify x (pointed to by ptr) since *ptr declared constant. Cannot modify ptr to point to new address since ptr is constant.
79.
Pointer Expressions andPointer Arithmetic Pointer arithmetic Increment/decrement pointer (++ or --) Add/subtract an integer to/from a pointer( + or += , - or -=) Pointers may be subtracted from each other Pointer arithmetic meaningless unless performed on pointer to array 5 element int array on a machine using 4 byte ints vPtr points to first element v[ 0 ], which is at location 3000 vPtr = 3000 vPtr += 2; sets vPtr to 3008 vPtr points to v[ 2 ] pointer variable vPtr v[0] v[1] v[2] v[4]v[3] 3000 3004 3008 3012 3016 location
80.
Pointer Expressions andPointer Arithmetic Subtracting pointers Returns number of elements between two addresses vPtr2 = v[ 2 ]; vPtr = v[ 0 ]; vPtr2 - vPtr == 2 Pointer assignment Pointer can be assigned to another pointer if both of same type If not same type, cast operator must be used Exception: pointer to void (type void *) Generic pointer, represents any type No casting needed to convert pointer to void pointer void pointers cannot be dereferenced
81.
Pointer Expressions andPointer Arithmetic Pointer comparison Use equality and relational operators Comparisons meaningless unless pointers point to members of same array Compare addresses stored in pointers Example: could show that one pointer points to higher numbered element of array than other pointer Common use to determine whether pointer is 0 (does not point to anything)
82.
Relationship Between Pointers andArrays Arrays and pointers closely related Array name like constant pointer Pointers can do array subscripting operations Accessing array elements with pointers Element b[ n ] can be accessed by *( bPtr + n ) Called pointer/offset notation Addresses &b[ 3 ] same as bPtr + 3 Array name can be treated as pointer b[ 3 ] same as *( b + 3 ) Pointers can be subscripted (pointer/subscript notation) bPtr[ 3 ] same as b[ 3 ]
83.
Arrays of Pointers Arrays can contain pointers Commonly used to store array of strings char *suit[ 4 ] = {"Hearts", "Diamonds", "Clubs", "Spades" }; Each element of suit points to char * (a string) Array does not store strings, only pointers to strings suit array has fixed size, but strings can be of any size suit[3] suit[2] suit[1] suit[0] ’H’ ’e’ ’a’ ’r’ ’t’ ’s’ ’0’ ’D’ ’i’ ’a’ ’m’ ’o’ ’n’ ’d’ ’s’ ’0’ ’C’ ’l’ ’u’ ’b’ ’s’ ’0’ ’S’ ’p’ ’a’ ’d’ ’e’ ’s’ ’0’
84.
Function Pointers Callingfunctions using pointers Assume parameter: bool ( *compare ) ( int, int ) Execute function with either ( *compare ) ( int1, int2 ) Dereference pointer to function to execute OR compare( int1, int2 ) Could be confusing User may think compare name of actual function in program
85.
1 // Example5 2 // Multipurpose sorting program using function pointers. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 #include <iomanip> 10 11 using std::setw; 12 13 // prototypes 14 void bubble( int [], const int, bool (*)( int, int ) ); 15 void swap( int * const, int * const ); 16 bool ascending( int, int ); 17 bool descending( int, int ); 18 19 int main() 20 { 21 const int arraySize = 10; 22 int order; 23 int counter; 24 int a[ arraySize ] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 }; 25 Parameter is pointer to function that receives two integer parameters and returns bool result.
86.
26 cout <<"Enter 1 to sort in ascending order,n" 27 << "Enter 2 to sort in descending order: "; 28 cin >> order; 29 cout << "nData items in original ordern"; 30 31 // output original array 32 for ( counter = 0; counter < arraySize; counter++ ) 33 cout << setw( 4 ) << a[ counter ]; 34 35 // sort array in ascending order; pass function ascending 36 // as an argument to specify ascending sorting order 37 if ( order == 1 ) { 38 bubble( a, arraySize, ascending ); 39 cout << "nData items in ascending ordern"; 40 } 41 42 // sort array in descending order; pass function descending 43 // as an agrument to specify descending sorting order 44 else { 45 bubble( a, arraySize, descending ); 46 cout << "nData items in descending ordern"; 47 } 48
87.
49 // outputsorted array 50 for ( counter = 0; counter < arraySize; counter++ ) 51 cout << setw( 4 ) << a[ counter ]; 52 53 cout << endl; 54 55 return 0; // indicates successful termination 56 57 } // end main 58 59 // multipurpose bubble sort; parameter compare is a pointer to 60 // the comparison function that determines sorting order 61 void bubble( int work[], const int size, 62 bool (*compare)( int, int ) ) 63 { 64 // loop to control passes 65 for ( int pass = 1; pass < size; pass++ ) 66 67 // loop to control number of comparisons per pass 68 for ( int count = 0; count < size - 1; count++ ) 69 70 // if adjacent elements are out of order, swap them 71 if ( (*compare)( work[ count ], work[ count + 1 ] ) ) 72 swap( &work[ count ], &work[ count + 1 ] ); compare is pointer to function that receives two integer parameters and returns bool result. Parentheses necessary to indicate pointer to function Call passed function compare; dereference pointer to execute function.
88.
73 74 } //end function bubble 75 76 // swap values at memory locations to which 77 // element1Ptr and element2Ptr point 78 void swap( int * const element1Ptr, int * const element2Ptr ) 79 { 80 int hold = *element1Ptr; 81 *element1Ptr = *element2Ptr; 82 *element2Ptr = hold; 83 84 } // end function swap 85 86 // determine whether elements are out of order 87 // for an ascending order sort 88 bool ascending( int a, int b ) 89 { 90 return b < a; // swap if b is less than a 91 92 } // end function ascending 93
89.
94 // determinewhether elements are out of order 95 // for a descending order sort 96 bool descending( int a, int b ) 97 { 98 return b > a; // swap if b is greater than a 99 100 } // end function descending Enter 1 to sort in ascending order, Enter 2 to sort in descending order: 1 Data items in original order 2 6 4 8 10 12 89 68 45 37 Data items in ascending order 2 4 6 8 10 12 37 45 68 89 Enter 1 to sort in ascending order, Enter 2 to sort in descending order: 2 Data items in original order 2 6 4 8 10 12 89 68 45 37 Data items in descending order 89 68 45 37 12 10 8 6 4 2
90.
Function Pointers Arraysof pointers to functions Menu-driven systems Pointers to each function stored in array of pointers to functions All functions must have same return type and same parameter types Menu choice subscript into array of function pointers
91.
1 // Example6 2 // Demonstrating an array of pointers to functions. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 // function prototypes 10 void function1( int ); 11 void function2( int ); 12 void function3( int ); 13 14 int main() 15 { 16 // initialize array of 3 pointers to functions that each 17 // take an int argument and return void 18 void (*f[ 3 ])( int ) = { function1, function2, function3 }; 19 20 int choice; 21 22 cout << "Enter a number between 0 and 2, 3 to end: "; 23 cin >> choice; 24 Array initialized with names of three functions; function names are pointers.
92.
25 // processuser's choice 26 while ( choice >= 0 && choice < 3 ) { 27 28 // invoke function at location choice in array f 29 // and pass choice as an argument 30 (*f[ choice ])( choice ); 31 32 cout << "Enter a number between 0 and 2, 3 to end: "; 33 cin >> choice; 34 } 35 36 cout << "Program execution completed." << endl; 37 38 return 0; // indicates successful termination 39 40 } // end main 41 42 void function1( int a ) 43 { 44 cout << "You entered " << a 45 << " so function1 was callednn"; 46 47 } // end function1 48 Call chosen function by dereferencing corresponding element in array.
93.
25 // processuser's choice 26 while ( choice >= 0 && choice < 3 ) { 27 28 // invoke function at location choice in array f 29 // and pass choice as an argument 30 (*f[ choice ])( choice ); 31 32 cout << "Enter a number between 0 and 2, 3 to end: "; 33 cin >> choice; 34 } 35 36 cout << "Program execution completed." << endl; 37 38 return 0; // indicates successful termination 39 40 } // end main 41 42 void function1( int a ) 43 { 44 cout << "You entered " << a 45 << " so function1 was callednn"; 46 47 } // end function1 48 Call chosen function by dereferencing corresponding element in array.
94.
Fundamentals of Charactersand Strings Character constant Integer value represented as character in single quotes 'z' is integer value of z 122 in ASCII String Series of characters treated as single unit Can include letters, digits, special characters +, -, * ... String literal (string constants) Enclosed in double quotes, for example: "I like C++" Array of characters, ends with null character '0' String is constant pointer Pointer to string’s first character Like arrays
95.
Fundamentals of Charactersand Strings String assignment Character array char color[] = "blue"; Creates 5 element char array color last element is '0' Variable of type char * char *colorPtr = "blue"; Creates pointer colorPtr to letter b in string “blue” “blue” somewhere in memory Alternative for character array char color[] = { ‘b’, ‘l’, ‘u’, ‘e’, ‘0’ };
96.
Fundamentals of Charactersand Strings Reading strings Assign input to character array word[ 20 ] cin >> word Reads characters until whitespace or EOF String could exceed array size cin >> setw( 20 ) >> word; Reads 19 characters (space reserved for '0')
97.
Fundamentals of Charactersand Strings cin.getline Read line of text cin.getline( array, size, delimiter ); Copies input into specified array until either One less than size is reached delimiter character is input Example char sentence[ 80 ]; cin.getline( sentence, 80, 'n' );
98.
String Manipulation Functionsof the String- handling Library String handling library <cstring> provides functions to Manipulate string data Compare strings Search strings for characters and other strings Tokenize strings (separate strings into logical pieces)
99.
String Manipulation Functionsof the String- handling Library char *strcpy( char *s1, const char *s2 ); Copies the string s2 into the character array s1. The value of s1 is returned. char *strncpy( char *s1, const char *s2, size_t n ); Copies at most n characters of the string s2 into the character array s1. The value of s1 is returned. char *strcat( char *s1, const char *s2 ); Appends the string s2 to the string s1. The first character of s2 overwrites the terminating null character of s1. The value of s1 is returned. char *strncat( char *s1, const char *s2, size_t n ); Appends at most n characters of string s2 to string s1. The first character of s2 overwrites the terminating null character of s1. The value of s1 is returned. int strcmp( const char *s1, const char *s2 ); Compares the string s1 with the string s2. The function returns a value of zero, less than zero or greater than zero if s1 is equal to, less than or greater than s2, respectively.
100.
String Manipulation Functionsof the String-handling Library int strncmp( const char *s1, const char *s2, size_t n ); Compares up to n characters of the string s1 with the string s2. The function returns zero, less than zero or greater than zero if s1 is equal to, less than or greater than s2, respectively. char *strtok( char *s1, const char *s2 ); A sequence of calls to strtok breaks string s1 into “tokens”—logical pieces such as words in a line of text— delimited by characters contained in string s2. The first call contains s1 as the first argument, and subsequent calls to continue tokenizing the same string contain NULL as the first argument. A pointer to the current token is returned by each call. If there are no more tokens when the function is called, NULL is returned. size_t strlen( const char *s ); Determines the length of string s. The number of characters preceding the terminating null character is returned.
101.
Structure Definitions Structures Aggregate data types built using elements of other types struct Time { int hour; int minute; int second; }; Structure member naming In same struct: must have unique names In different structs: can share name struct definition must end with semicolon Structure tag Structure members Structure
102.
Structure Definitions Self-referentialstructure Structure member cannot be instance of enclosing struct Structure member can be pointer to instance of enclosing struct (self-referential structure) Used for linked lists, queues, stacks and trees struct definition Creates new data type used to declare variables Structure variables declared like variables of other types Examples: Time timeObject; Time timeArray[ 10 ]; Time *timePtr; Time &timeRef = timeObject;
103.
Accessing Structure Members Member access operators Dot operator (.) for structure and class members Arrow operator (->) for structure and class members via pointer to object Print member hour of timeObject: cout << timeObject.hour; OR timePtr = &timeObject; cout << timePtr->hour; timePtr->hour same as ( *timePtr ).hour Parentheses required * lower precedence than .
104.
Implementing a User-Defined TypeTime with a struct Default: structures passed by value Pass structure by reference Avoid overhead of copying structure C-style structures No “interface” If implementation changes, all programs using that struct must change accordingly Cannot print as unit Must print/format member by member Cannot compare in entirety Must compare member by member
105.
1 // Example7 2 // Create a structure, set its members, and print it. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <iomanip> 9 10 using std::setfill; 11 using std::setw; 12 13 // structure definition 14 struct Time { 15 int hour; // 0-23 (24-hour clock format) 16 int minute; // 0-59 17 int second; // 0-59 18 19 }; // end struct Time 20 21 void printUniversal( const Time & ); // prototype 22 void printStandard( const Time & ); // prototype 23 Define structure type Time with three integer members. Pass references to constant Time objects to eliminate copying overhead.
106.
Class Classes(keyword class) Model objects Attributes (data members) Behaviors (member functions) Methods Invoked in response to messages Member access specifiers: public, Private, protected: Constructor function Special member function Initializes data members Same name as class Called when object instantiated Several constructors Function overloading No return type
107.
Implementing a TimeAbstract Data Type with a class Objects of class After class definition Class name new type specifier Object, array, pointer and reference declarations Member functions defined outside class Time sunset; // object of type Time Time arrayOfTimes[ 5 ]; // array of Time objects Time *pointerToTime; // pointer to a Time object Time &dinnerTime = sunset; // reference to a Time object Class name becomes new type specifier. Binary scope resolution (::) ReturnType ClassName::MemberFunctionName( ){…} Member functions defined inside class Do not need scope resolution operator, class name Compiler attempts inline Outside class, inline explicitly with keyword inline
108.
1 // Example8 2 // Time class. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <iomanip> 9 10 using std::setfill; 11 using std::setw; 12 13 // Time abstract data type (ADT) definition 14 class Time { 15 16 public: 17 Time(); // constructor 18 void setTime( int, int, int ); // set hour, minute, second 19 void printUniversal(); // print universal-time format 20 void printStandard(); // print standard-time format 21 Define class Time.
109.
22 private: 23 inthour; // 0 - 23 (24-hour clock format) 24 int minute; // 0 - 59 25 int second; // 0 - 59 26 27 }; // end class Time 28 29 // Time constructor initializes each data member to zero and 30 // ensures all Time objects start in a consistent state 31 Time::Time() 32 { 33 hour = minute = second = 0; 34 35 } // end Time constructor 36 37 // set new Time value using universal time, perform validity 38 // checks on the data values and set invalid values to zero 39 void Time::setTime( int h, int m, int s ) 40 { 41 hour = ( h >= 0 && h < 24 ) ? h : 0; 42 minute = ( m >= 0 && m < 60 ) ? m : 0; 43 second = ( s >= 0 && s < 60 ) ? s : 0; 44 45 } // end function setTime 46 Constructor initializes private data members to 0. public member function checks parameter values for validity before setting private data members.
110.
47 // printTime in universal format 48 void Time::printUniversal() 49 { 50 cout << setfill( '0' ) << setw( 2 ) << hour << ":" 51 << setw( 2 ) << minute << ":" 52 << setw( 2 ) << second; 53 54 } // end function printUniversal 55 56 // print Time in standard format 57 void Time::printStandard() 58 { 59 cout << ( ( hour == 0 || hour == 12 ) ? 12 : hour % 12 ) 60 << ":" << setfill( '0' ) << setw( 2 ) << minute 61 << ":" << setw( 2 ) << second 62 << ( hour < 12 ? " AM" : " PM" ); 63 64 } // end function printStandard 65 66 int main() 67 { 68 Time t; // instantiate object t of class Time 69 Declare variable t to be object of class Time. No arguments (implicitly “know” purpose is to print data members); member function calls more concise.
111.
70 // outputTime object t's initial values 71 cout << "The initial universal time is "; 72 t.printUniversal(); // 00:00:00 73 74 cout << "nThe initial standard time is "; 75 t.printStandard(); // 12:00:00 AM 76 77 t.setTime( 13, 27, 6 ); // change time 78 79 // output Time object t's new values 80 cout << "nnUniversal time after setTime is "; 81 t.printUniversal(); // 13:27:06 82 83 cout << "nStandard time after setTime is "; 84 t.printStandard(); // 1:27:06 PM 85 86 t.setTime( 99, 99, 99 ); // attempt invalid settings 87 88 // output t's values after specifying invalid values 89 cout << "nnAfter attempting invalid settings:" 90 << "nUniversal time: "; 91 t.printUniversal(); // 00:00:00 92 Invoke public member functions to print time. Set data members using public member function. Attempt to set data members to invalid values using public member function.
112.
93 cout <<"nStandard time: "; 94 t.printStandard(); // 12:00:00 AM 95 cout << endl; 96 97 return 0; 98 99 } // end main The initial universal time is 00:00:00 The initial standard time is 12:00:00 AM Universal time after setTime is 13:27:06 Standard time after setTime is 1:27:06 PM After attempting invalid settings: Universal time: 00:00:00 Standard time: 12:00:00 AM Data members set to 0 after attempting invalid settings.
113.
Classes Destructors Samename as class Preceded with tilde (~) No arguments Cannot be overloaded Performs “termination housekeeping” Advantages of using classes Simplify programming Interfaces Hide implementation Software reuse Composition (aggregation) Class objects included as members of other classes Inheritance New classes derived from old
114.
Class Scope andAccessing Class Members Class scope Data members, member functions Within class scope Class members Immediately accessible by all member functions Referenced by name Outside class scope Referenced through handles Object name, reference to object, pointer to object File scope Nonmember functions
115.
Class Scope andAccessing Class Members Function scope Variables declared in member function Only known to function Variables with same name as class-scope variables Class-scope variable “hidden” Access with scope resolution operator (::) ClassName::classVariableName Variables only known to function they are defined in Variables are destroyed after function completion Operators to access class members Identical to those for structs Dot member selection operator (.) Object Reference to object Arrow member selection operator (->) Pointers
116.
1 // Example9 2 // Demonstrating the class member access operators . and -> 3 // 4 // CAUTION: IN FUTURE EXAMPLES WE AVOID PUBLIC DATA! 5 #include <iostream> 6 7 using std::cout; 8 using std::endl; 9 10 // class Count definition 11 class Count { 12 13 public: 14 int x; 15 16 void print() 17 { 18 cout << x << endl; 19 } 20 21 }; // end class Count 22 Data member x public to illustrate class member access operators; typically data members private.
117.
Separating Interface from Implementation Separatinginterface from implementation Advantage: Easier to modify programs Disadvantage Header files Portions of implementation: Inline member functions Hints about other implementation: private members Can hide more with proxy class Header files Class definitions and function prototypes Included in each file using class #include File extension .h Source-code files Member function definitions Same base name Convention Compiled and linked
118.
Controlling Access toMembers Access modes private Default access mode Accessible to member functions and friends public Accessible to any function in program with handle to class object protected (later) Class member access Default private Explicitly set to private, public, protected struct member access Default public Explicitly set to private, public, protected
119.
Access Functions andUtility Functions Access to class’s private data Controlled with access functions (accessor methods) Get function - Read private data Set function - Modify private data Access functions public Read/display data Predicate functions Check conditions Utility functions (helper functions) private Support operation of public member functions Not intended for direct client use
120.
1 // Example10 2 // SalesPerson class definition. 3 // Member functions defined in salesp.cpp. 4 #ifndef SALESP_H 5 #define SALESP_H 6 7 class SalesPerson { 8 9 public: 10 SalesPerson(); // constructor 11 void getSalesFromUser(); // input sales from keyboard 12 void setSales( int, double ); // set sales for a month 13 void printAnnualSales(); // summarize and print sales 14 15 private: 16 double totalAnnualSales(); // utility function 17 double sales[ 12 ]; // 12 monthly sales figures 18 19 }; // end class SalesPerson 20 21 #endif Set access function performs validity checks. private utility function.
121.
25 // get12 sales figures from the user at the keyboard 26 void SalesPerson::getSalesFromUser() 27 { 28 double salesFigure; 29 30 for ( int i = 1; i <= 12; i++ ) { 31 cout << "Enter sales amount for month " << i << ": "; 32 cin >> salesFigure; 33 setSales( i, salesFigure ); 34 35 } // end for 36 37 } // end function getSalesFromUser 38 39 // set one of the 12 monthly sales figures; function subtracts 40 // one from month value for proper subscript in sales array 41 void SalesPerson::setSales( int month, double amount ) 42 { 43 // test for valid month and amount values 44 if ( month >= 1 && month <= 12 && amount > 0 ) 45 sales[ month - 1 ] = amount; // adjust for subscripts 0-11 46 47 else // invalid month or amount value 48 cout << "Invalid month or sales figure" << endl; Set access function performs validity checks.
122.
Initializing Class Objects: Constructors Constructors Initializedata members; no return type Or can set later Same name as class Can specify default arguments Default constructors Defaults all arguments OR Explicitly requires no arguments Can be invoked with no arguments Only one per class Initializers Passed as arguments to constructor In parentheses to right of class name before semicolon Class-type ObjectName( value1,value2,…);
123.
1 // Example11 2 // Declaration of class Time. 3 // Member functions defined in time2.cpp. 4 5 // prevent multiple inclusions of header file 6 #ifndef TIME2_H 7 #define TIME2_H 8 9 // Time abstract data type definition 10 class Time { 11 12 public: 13 Time( int = 0, int = 0, int = 0); // default constructor 14 void setTime( int, int, int ); // set hour, minute, second 15 void printUniversal(); // print universal-time format 16 void printStandard(); // print standard-time format 17 18 private: 19 int hour; // 0 - 23 (24-hour clock format) 20 int minute; // 0 - 59 21 int second; // 0 - 59 22 23 }; // end class Time 24 25 #endif Default constructor specifying all arguments.
124.
1 // Example12 2 // Member-function definitions for class Time. 3 #include <iostream> 4 5 using std::cout; 6 7 #include <iomanip> 8 9 using std::setfill; 10 using std::setw; 11 12 // include definition of class Time from time2.h 13 #include "time2.h" 14 15 // Time constructor initializes each data member to zero; 16 // ensures all Time objects start in a consistent state 17 Time::Time( int hr, int min, int sec ) 18 { 19 setTime( hr, min, sec ); // validate and set time 20 21 } // end Time constructor 22 Constructor calls setTime to validate passed (or default) values.
125.
23 // setnew Time value using universal time, perform validity 24 // checks on the data values and set invalid values to zero 25 void Time::setTime( int h, int m, int s ) 26 { 27 hour = ( h >= 0 && h < 24 ) ? h : 0; 28 minute = ( m >= 0 && m < 60 ) ? m : 0; 29 second = ( s >= 0 && s < 60 ) ? s : 0; 30 31 } // end function setTime 32 33 // print Time in universal format 34 void Time::printUniversal() 35 { 36 cout << setfill( '0' ) << setw( 2 ) << hour << ":" 37 << setw( 2 ) << minute << ":" 38 << setw( 2 ) << second; 39 40 } // end function printUniversal 41
126.
1 // Example13 2 // Demonstrating a default constructor for class Time. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 // include definition of class Time from time2.h 9 #include "time2.h" 10 11 int main() 12 { 13 Time t1; // all arguments defaulted 14 Time t2( 2 ); // minute and second defaulted 15 Time t3( 21, 34 ); // second defaulted 16 Time t4( 12, 25, 42 ); // all values specified 17 Time t5( 27, 74, 99 ); // all bad values specified 18 19 cout << "Constructed with:nn" 20 << "all default arguments:n "; 21 t1.printUniversal(); // 00:00:00 22 cout << "n "; 23 t1.printStandard(); // 12:00:00 AM 24 Initialize Time objects using default arguments. Initialize Time object with invalid values; validity checking will set values to 0.
Destructors Destructors Specialmember function Same name as class preceded with tilde (~) No arguments; No return value Cannot be overloaded Performs “termination housekeeping” Before system reclaims object’s memory Reuse memory for new objects No explicit destructor Compiler creates “empty destructor” Constructors and destructors - Called implicitly by compiler Order of function calls Depends on when execution enters and exits scope of objects Generally, destructor calls reverse order of constructor calls
129.
When Constructors and DestructorsAre Called Global scope objects Constructors - Before any other function (including main) Destructors When main terminates (or exit function called) Not called if program terminates with abort Automatic local objects Constructors - When objects defined & each time execution enters scope Destructors When objects leave scope Execution exits block in which object defined Not called if program ends with exit or abort static local objects Constructors Exactly once When execution reaches point where object defined Destructors When main terminates or exit function called Not called if program ends with abort
130.
1 // Example14 2 // Demonstrating the order in which constructors and 3 // destructors are called. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 // include CreateAndDestroy class definition from create.h 10 #include "create.h" 11 12 void create( void ); // prototype 13 14 // global object 15 CreateAndDestroy first( 1, "(global before main)" ); 16 17 int main() 18 { 19 cout << "nMAIN FUNCTION: EXECUTION BEGINS" << endl; 20 21 CreateAndDestroy second( 2, "(local automatic in main)" ); 22 23 static CreateAndDestroy third( 24 3, "(local static in main)" ); 25 Create variable with global scope. Create local automatic object. Create static local object.
131.
26 create(); //call function to create objects 27 28 cout << "nMAIN FUNCTION: EXECUTION RESUMES" << endl; 29 30 CreateAndDestroy fourth( 4, "(local automatic in main)" ); 31 32 cout << "nMAIN FUNCTION: EXECUTION ENDS" << endl; 33 34 return 0; 35 36 } // end main 37 38 // function to create objects 39 void create( void ) 40 { 41 cout << "nCREATE FUNCTION: EXECUTION BEGINS" << endl; 42 43 CreateAndDestroy fifth( 5, "(local automatic in create)" ); 44 45 static CreateAndDestroy sixth( 46 6, "(local static in create)" ); 47 48 CreateAndDestroy seventh( 49 7, "(local automatic in create)" ); 50 cout << "nCREATE FUNCTION: EXECUTION ENDS" << endl; 52 53 } // end function create Create local automatic objects. Create local automatic object. Create local automatic object in function. Create static local object in function. Create local automatic object in function.
132.
Object 1 constructorruns (global before main) MAIN FUNCTION: EXECUTION BEGINS Object 2 constructor runs (local automatic in main) Object 3 constructor runs (local static in main) CREATE FUNCTION: EXECUTION BEGINS Object 5 constructor runs (local automatic in create) Object 6 constructor runs (local static in create) Object 7 constructor runs (local automatic in create) CREATE FUNCTION: EXECUTION ENDS Object 7 destructor runs (local automatic in create) Object 5 destructor runs (local automatic in create) MAIN FUNCTION: EXECUTION RESUMES Object 4 constructor runs (local automatic in main) MAIN FUNCTION: EXECUTION ENDS Object 4 destructor runs (local automatic in main) Object 2 destructor runs (local automatic in main) Object 6 destructor runs (local static in create) Object 3 destructor runs (local static in main) Object 1 destructor runs (global before main) Destructors for local automatic objects in main called in reverse order of constructors. Local static object exists until program termination.Global object constructed before main execution and destroyed last. Local automatic objects destroyed after function execution ends in reverse order of construction. Local static object constructed on first function call and destroyed after main execution ends.
133.
Using Set andGet Functions Set functions Perform validity checks before modifying private data Notify if invalid values Indicate with return values Get functions “Query” functions Control format of data returned
134.
Subtle Trap: Returninga Reference to a private Data Member Reference to object &pRef = p; Alias for name of object Lvalue Can receive value in assignment statement Changes original object Returning references public member functions can return non-const references to private data members Client able to modify private data members
135.
1 // Example15 2 // Declaration of class Time. 3 // Member functions defined in time4.cpp 4 5 // prevent multiple inclusions of header file 6 #ifndef TIME4_H 7 #define TIME4_H 8 9 class Time { 10 11 public: 12 Time( int = 0, int = 0, int = 0 ); 13 void setTime( int, int, int ); 14 int getHour(); 15 16 int &badSetHour( int ); // DANGEROUS reference return 17 18 private: 19 int hour; 20 int minute; 21 int second; 22 23 }; // end class Time 24 25 #endif Function to demonstrate effects of returning reference to private data member.
136.
25 // returnhour value 26 int Time::getHour() 27 { 28 return hour; 29 30 } // end function getHour 31 32 // POOR PROGRAMMING PRACTICE: 33 // Returning a reference to a private data member. 34 int &Time::badSetHour( int hh ) 35 { 36 hour = ( hh >= 0 && hh < 24 ) ? hh : 0; 37 38 return hour; // DANGEROUS reference return 39 40 } // end function badSetHour Return reference to private data member hour.
137.
1 // Example16 2 // Demonstrating a public member function that 3 // returns a reference to a private data member. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 // include definition of class Time from time4.h 10 #include "time4.h" 11 12 int main() 13 { 14 Time t; 15 16 // store in hourRef the reference returned by badSetHour 17 int &hourRef = t.badSetHour( 20 ); 18 19 cout << "Hour before modification: " << hourRef; 20 21 // use hourRef to set invalid value in Time object t 22 hourRef = 30; 23 24 cout << "nHour after modification: " << t.getHour(); 25 badSetHour returns reference to private data member hour. Reference allows setting of private data member hour.
138.
26 // Dangerous:Function call that returns 27 // a reference can be used as an lvalue! 28 t.badSetHour( 12 ) = 74; 29 30 cout << "nn*********************************n" 31 << "POOR PROGRAMMING PRACTICE!!!!!!!!n" 32 << "badSetHour as an lvalue, Hour: " 33 << t.getHour() 34 << "n*********************************" << endl; 35 36 return 0; 37 38 } // end main Hour before modification: 20 Hour after modification: 30 ********************************* POOR PROGRAMMING PRACTICE!!!!!!!! badSetHour as an lvalue, Hour: 74 ********************************* Can use function call as lvalue to set invalid value. Returning reference allowed invalid setting of private data member hour.
139.
Default Memberwise Assignment Assigningobjects Assignment operator (=) Can assign one object to another of same type Default: memberwise assignment Each right member assigned individually to left member Passing, returning objects Objects passed as function arguments Objects returned from functions Default: pass-by-value Copy of object passed, returned Copy constructor Copy original values into new object
140.
1 // Example17 2 // Demonstrating that class objects can be assigned 3 // to each other using default memberwise assignment. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 // class Date definition 10 class Date { 11 12 public: 13 Date( int = 1, int = 1, int = 1990 ); // default constructor 14 void print(); 15 16 private: 17 int month; 18 int day; 19 int year; 20 21 }; // end class Date 22
141.
Software Reusability Softwarereusability Class libraries Well-defined Carefully tested Well-documented Portable Widely available Speeds development of powerful, high-quality software Rapid applications development (RAD) Resulting problems Cataloging schemes Licensing schemes Protection mechanisms
142.
const (Constant) Objectsand const Member Functions Keyword const Specify object not modifiable Compiler error if attempt to modify const object Example const Time noon( 12, 0, 0 ); Declares const object noon of class Time Initializes to 12 const member functions Member functions for const objects must also be const Cannot modify object Specify const in both prototype and definition Prototype After parameter list Definition Before beginning left brace
143.
const (Constant) Objectsand const Member Functions Constructors and destructors Cannot be const Must be able to modify objects Constructor Initializes objects Destructor Performs termination housekeeping Member initializer syntax Initializing with member initializer syntax Can be used for All data members Must be used for const data members Data members that are references
144.
1 // Example18 2 // Using a member initializer to initialize a 3 // constant of a built-in data type. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 class Increment { 10 11 public: 12 Increment( int c = 0, int i = 1 ); // default constructor 13 14 void addIncrement() 15 { 16 count += increment; 17 18 } // end function addIncrement 19 20 void print() const; // prints count and increment 21
145.
22 private: 23 intcount; 24 const int increment; // const data member 25 26 }; // end class Increment 27 28 // constructor 29 Increment::Increment( int c, int i ) 30 : count( c ), // initializer for non-const member 31 increment( i ) // required initializer for const member 32 { 33 // empty body 34 35 } // end Increment constructor 36 37 // print count and increment values 38 void Increment::print() const 39 { 40 cout << "count = " << count 41 << ", increment = " << increment << endl; 42 43 } // end function print 44 Declare increment as const data member. Member initializer list separated from parameter list by colon. Member initializer syntax can be used for non-const data member count. Member initializer syntax must be used for const data member increment. Member initializer consists of data member name (increment) followed by parentheses containing initial value (c).
146.
Composition: Objects asMembers of Classes Composition Class has objects of other classes as members Construction of objects Member objects constructed in order declared Not in order of constructor’s member initializer list Constructed before enclosing class objects (host objects)
147.
1 // Example19 2 // Date class definition. 3 // Member functions defined in date1.cpp 4 #ifndef DATE1_H 5 #define DATE1_H 6 7 class Date { 8 9 public: 10 Date( int = 1, int = 1, int = 1900 ); // default constructor 11 void print() const; // print date in month/day/year format 12 ~Date(); // provided to confirm destruction order 13 14 private: 15 int month; // 1-12 (January-December) 16 int day; // 1-31 based on month 17 int year; // any year 18 19 // utility function to test proper day for month and year 20 int checkDay( int ) const; 21 22 }; // end class Date 23 24 #endif Note no constructor with parameter of type Date. Recall compiler provides default copy constructor.
148.
1 // EXAMPLE20 2 // Employee class definition. 3 // Member functions defined in employee1.cpp. 4 #ifndef EMPLOYEE1_H 5 #define EMPLOYEE1_H 6 7 // include Date class definition from date1.h 8 #include "date1.h" 9 10 class Employee { 11 12 public: 13 Employee( 14 const char *, const char *, const Date &, const Date & ); 15 16 void print() const; 17 ~Employee(); // provided to confirm destruction order 18 19 private: 20 char firstName[ 25 ]; 21 char lastName[ 25 ]; 22 const Date birthDate; // composition: member object 23 const Date hireDate; // composition: member object 24 25 }; // end class Employee Using composition; Employee object contains Date objects as data members.
149.
13 // constructoruses member initializer list to pass initializer 14 // values to constructors of member objects birthDate and 15 // hireDate [Note: This invokes the so-called "default copy 16 // constructor" which the C++ compiler provides implicitly.] 17 Employee::Employee( const char *first, const char *last, 18 const Date &dateOfBirth, const Date &dateOfHire ) 19 : birthDate( dateOfBirth ), // initialize birthDate 20 hireDate( dateOfHire ) // initialize hireDate 21 { 22 // copy first into firstName and be sure that it fits 23 int length = strlen( first ); 24 length = ( length < 25 ? length : 24 ); 25 strncpy( firstName, first, length ); 26 firstName[ length ] = '0'; 27 28 // copy last into lastName and be sure that it fits 29 length = strlen( last ); 30 length = ( length < 25 ? length : 24 ); 31 strncpy( lastName, last, length ); 32 lastName[ length ] = '0'; 33 34 // output Employee object to show when constructor is called 35 cout << "Employee object constructor: " 36 << firstName << ' ' << lastName << endl; 37 Member initializer syntax to initialize Date data members birthDate and hireDate; compiler uses default copy constructor. Output to show timing of constructors.
150.
1 // Example21 2 // Demonstrating composition--an object with member objects. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include "employee1.h" // Employee class definition 9 10 int main() 11 { 12 Date birth( 7, 24, 1949 ); 13 Date hire( 3, 12, 1988 ); 14 Employee manager( "Bob", "Jones", birth, hire ); 15 16 cout << 'n'; 17 manager.print(); 18 19 cout << "nTest Date constructor with invalid values:n"; 20 Date lastDayOff( 14, 35, 1994 ); // invalid month and day 21 cout << endl; 22 23 return 0; 24 25 } // end main Create Date objects to pass to Employee constructor.
151.
friend Functions andfriend Classes friend function Defined outside class’s scope Right to access non-public members Declaring friends Function Precede function prototype with keyword friend Want to make all member functions of class ClassTwo as friends of class ClassOne Place declaration of form friend class ClassTwo; in ClassOne definition
152.
friend Functions and friendClasses Properties of friendship Friendship granted, not taken Class B friend of class A Class A must explicitly declare class B friend Not symmetric Class B friend of class A Class A not necessarily friend of class B Not transitive Class A friend of class B Class B friend of class C Class A not necessarily friend of Class C
153.
1 // Example22 2 // Friends can access private members of a class. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 // Count class definition 9 class Count { 10 friend void setX( Count &, int ); // friend declaration 11 12 public: 13 14 // constructor 15 Count() 16 : x( 0 ) // initialize x to 0 17 { 18 // empty body 19 20 } // end Count constructor 21 Precede function prototype with keyword friend.
154.
22 // outputx 23 void print() const 24 { 25 cout << x << endl; 26 27 } // end function print 28 29 private: 30 int x; // data member 31 32 }; // end class Count 33 34 // function setX can modify private data of Count 35 // because setX is declared as a friend of Count 36 void setX( Count &c, int val ) 37 { 38 c.x = val; // legal: setX is a friend of Count 39 40 } // end function setX 41 Pass Count object since C- style, standalone function. Since setX friend of Count, can access and modify private data member x.
155.
42 int main() 43{ 44 Count counter; // create Count object 45 46 cout << "counter.x after instantiation: "; 47 counter.print(); 48 49 setX( counter, 8 ); // set x with a friend 50 51 cout << "counter.x after call to setX friend function: "; 52 counter.print(); 53 54 return 0; 55 56 } // end main counter.x after instantiation: 0 counter.x after call to setX friend function: 8 Use friend function to access and modify private data member x.
156.
Using the thisPointer this pointer Allows object to access own address Not part of object itself Implicit argument to non-static member function call Implicitly reference member data and functions Type of this pointer depends on Type of object Whether member function is const In non-const member function of Employee this has type Employee * const Constant pointer to non-constant Employee object In const member function of Employee this has type const Employee * const Constant pointer to constant Employee object
157.
1 // Example23 2 // Using the this pointer to refer to object members. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 class Test { 9 10 public: 11 Test( int = 0 ); // default constructor 12 void print() const; 13 14 private: 15 int x; 16 17 }; // end class Test 18 19 // constructor 20 Test::Test( int value ) 21 : x( value ) // initialize x to value 22 { 23 // empty body 24 25 } // end Test constructor
158.
26 27 // printx using implicit and explicit this pointers; 28 // parentheses around *this required 29 void Test::print() const 30 { 31 // implicitly use this pointer to access member x 32 cout << " x = " << x; 33 34 // explicitly use this pointer to access member x 35 cout << "n this->x = " << this->x; 36 37 // explicitly use dereferenced this pointer and 38 // the dot operator to access member x 39 cout << "n(*this).x = " << ( *this ).x << endl; 40 41 } // end function print 42 43 int main() 44 { 45 Test testObject( 12 ); 46 47 testObject.print(); 48 49 return 0; 50 Implicitly use this pointer; only specify name of data member (x). Explicitly use this pointer with arrow operator. Explicitly use this pointer; dereference this pointer first, then use dot operator. 51 } // end main x = 12 this->x = 12 (*this).x = 12
159.
Using the thisPointer Cascaded member function calls Multiple functions invoked in same statement Function returns reference pointer to same object { return *this; } Other functions operate on that pointer Functions that do not return references must be called last
160.
1 // Example24 2 // Cascading member function calls. 3 4 // Time class definition. 5 // Member functions defined in time6.cpp. 6 #ifndef TIME6_H 7 #define TIME6_H 8 9 class Time { 10 11 public: 12 Time( int = 0, int = 0, int = 0 ); // default constructor 13 14 // set functions 15 Time &setTime( int, int, int ); // set hour, minute, second 16 Time &setHour( int ); // set hour 17 Time &setMinute( int ); // set minute 18 Time &setSecond( int ); // set second 19 20 // get functions (normally declared const) 21 int getHour() const; // return hour 22 int getMinute() const; // return minute 23 int getSecond() const; // return second 24 Set functions return reference to Time object to enable cascaded member function calls.
161.
25 // printfunctions (normally declared const) 26 void printUniversal() const; // print universal time 27 void printStandard() const; // print standard time 28 29 private: 30 int hour; // 0 - 23 (24-hour clock format) 31 int minute; // 0 - 59 32 int second; // 0 - 59 33 34 }; // end class Time 35 36 #endif
162.
1 // Example25 2 // Member-function definitions for Time class. 3 #include <iostream> 4 5 using std::cout; 6 7 #include <iomanip> 8 9 using std::setfill; 10 using std::setw; 11 12 #include "time6.h" // Time class definition 13 14 // constructor function to initialize private data; 15 // calls member function setTime to set variables; 16 // default values are 0 (see class definition) 17 Time::Time( int hr, int min, int sec ) 18 { 19 setTime( hr, min, sec ); 20 21 } // end Time constructor 22
163.
23 // setvalues of hour, minute, and second 24 Time &Time::setTime( int h, int m, int s ) 25 { 26 setHour( h ); 27 setMinute( m ); 28 setSecond( s ); 29 30 return *this; // enables cascading 31 32 } // end function setTime 33 34 // set hour value 35 Time &Time::setHour( int h ) 36 { 37 hour = ( h >= 0 && h < 24 ) ? h : 0; 38 39 return *this; // enables cascading 40 41 } // end function setHour 42 Return *this as reference to enable cascaded member function calls. Return *this as reference to enable cascaded member function calls.
164.
43 // setminute value 44 Time &Time::setMinute( int m ) 45 { 46 minute = ( m >= 0 && m < 60 ) ? m : 0; 47 48 return *this; // enables cascading 49 50 } // end function setMinute 51 52 // set second value 53 Time &Time::setSecond( int s ) 54 { 55 second = ( s >= 0 && s < 60 ) ? s : 0; 56 57 return *this; // enables cascading 58 59 } // end function setSecond 60 61 // get hour value 62 int Time::getHour() const 63 { 64 return hour; 65 66 } // end function getHour 67 Return *this as reference to enable cascaded member function calls. Return *this as reference to enable cascaded member function calls.
165.
68 // getminute value 69 int Time::getMinute() const 70 { 71 return minute; 72 73 } // end function getMinute 74 75 // get second value 76 int Time::getSecond() const 77 { 78 return second; 79 80 } // end function getSecond 81 82 // print Time in universal format 83 void Time::printUniversal() const 84 { 85 cout << setfill( '0' ) << setw( 2 ) << hour << ":" 86 << setw( 2 ) << minute << ":" 87 << setw( 2 ) << second; 88 89 } // end function printUniversal 90
1 // Example26 2 // Cascading member function calls with the this pointer. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include "time6.h" // Time class definition 9 10 int main() 11 { 12 Time t; 13 14 // cascaded function calls 15 t.setHour( 18 ).setMinute( 30 ).setSecond( 22 ); 16 17 // output time in universal and standard formats 18 cout << "Universal time: "; 19 t.printUniversal(); 20 21 cout << "nStandard time: "; 22 t.printStandard(); 23 24 cout << "nnNew standard time: "; 25 Cascade member function calls; recall dot operator associates from left to right.
168.
26 // cascadedfunction calls 27 t.setTime( 20, 20, 20 ).printStandard(); 28 29 cout << endl; 30 31 return 0; 32 33 } // end main Universal time: 18:30:22 Standard time: 6:30:22 PM New standard time: 8:20:20 PM Function call to printStandard must appear last; printStandard does not return reference to t.
169.
Dynamic Memory Managementwith Operators new and delete Dynamic memory management Control allocation and deallocation of memory Operators new and delete Include standard header <new> new Time *timePtr; timePtr = new Time; Creates object of proper size for type Time Error if no space in memory for object Calls default constructor for object Returns pointer of specified type Providing initializers double *ptr = new double( 3.14159 ); Time *timePtr = new Time( 12, 0, 0 ); Allocating arrays int *gradesArray = new int[ 10 ];
170.
Dynamic Memory Managementwith Operators new and delete delete Destroy dynamically allocated object and free space Consider delete timePtr; Operator delete Calls destructor for object Deallocates memory associated with object Memory can be reused to allocate other objects Deallocating arrays delete [] gradesArray; Deallocates array to which gradesArray points If pointer to array of objects First calls destructor for each object in array Then deallocates memory
171.
static Class Members static class variable “Class-wide” data Property of class, not specific object of class Efficient when single copy of data is enough Only the static variable has to be updated May seem like global variables, but have class scope Only accessible to objects of same class Initialized exactly once at file scope Exist even if no objects of class exist Can be public, private or protected
172.
static Class Members Accessingstatic class variables Accessible through any object of class public static variables Can also be accessed using binary scope resolution operator(::) Employee::count private static variables When no class member objects exist: Can only be accessed via public static member function Employee::getCount() static member functions Cannot access non-static data or functions No this pointer for static functions static data members and static member functions exist independent of objects
173.
1 // Example26 2 // Employee class definition. 3 #ifndef EMPLOYEE2_H 4 #define EMPLOYEE2_H 5 6 class Employee { 7 8 public: 9 Employee( const char *, const char * ); // constructor 10 ~Employee(); // destructor 11 const char *getFirstName() const; // return first name 12 const char *getLastName() const; // return last name 13 14 // static member function 15 static int getCount(); // return # objects instantiated 16 17 private: 18 char *firstName; 19 char *lastName; 20 21 // static data member 22 static int count; // number of objects instantiated 23 24 }; // end class Employee 25 static member function can only access static data members and member functions. static data member is class-wide data.
174.
1 // Example27 2 // Member-function definitions for class Employee. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <new> // C++ standard new operator 9 #include <cstring> // strcpy and strlen prototypes 10 11 #include "employee2.h" // Employee class definition 12 13 // define and initialize static data member 14 int Employee::count = 0; 15 16 // define static member function that returns number of 17 // Employee objects instantiated 18 int Employee::getCount() 19 { 20 return count; 21 22 } // end static function getCount Initialize static data member exactly once at file scope. static member function accesses static data member count.
175.
23 24 // constructordynamically allocates space for 25 // first and last name and uses strcpy to copy 26 // first and last names into the object 27 Employee::Employee( const char *first, const char *last ) 28 { 29 firstName = new char[ strlen( first ) + 1 ]; 30 strcpy( firstName, first ); 31 32 lastName = new char[ strlen( last ) + 1 ]; 33 strcpy( lastName, last ); 34 35 ++count; // increment static count of employees 36 37 cout << "Employee constructor for " << firstName 38 << ' ' << lastName << " called." << endl; 39 40 } // end Employee constructor 41 42 // destructor deallocates dynamically allocated memory 43 Employee::~Employee() 44 { 45 cout << "~Employee() called for " << firstName 46 << ' ' << lastName << endl; 47 new operator dynamically allocates space. Use static data member to store total count of employees.
176.
48 delete []firstName; // recapture memory 49 delete [] lastName; // recapture memory 50 51 --count; // decrement static count of employees 52 53 } // end destructor ~Employee 54 55 // return first name of employee 56 const char *Employee::getFirstName() const 57 { 58 // const before return type prevents client from modifying 59 // private data; client should copy returned string before 60 // destructor deletes storage to prevent undefined pointer 61 return firstName; 62 63 } // end function getFirstName 64 65 // return last name of employee 66 const char *Employee::getLastName() const 67 { 68 // const before return type prevents client from modifying 69 // private data; client should copy returned string before 70 // destructor deletes storage to prevent undefined pointer 71 return lastName; 72 73 } // end function getLastName Operator delete deallocates memory. Use static data member to store total count of employees.
177.
Data Abstraction and InformationHiding Information hiding Classes hide implementation details from clients Example: stack data structure Data elements added (pushed) onto top Data elements removed (popped) from top Last-in, first-out (LIFO) data structure Client only wants LIFO data structure Does not care how stack implemented Data abstraction Describe functionality of class independent of implementation
178.
Data Abstraction and InformationHiding Abstract data types (ADTs) Approximations/models of real-world concepts and behaviors int, float are models for a numbers Data representation Operations allowed on those data C++ extensible Standard data types cannot be changed, but new data types can be created
179.
Proxy Classes Proxyclass Hide implementation details of another class Knows only public interface of class being hidden Enables clients to use class’s services without giving access to class’s implementation Forward class declaration Used when class definition only uses pointer to another class Prevents need for including header file Declares class before referencing Format: class ClassToLoad;
180.
1 // Example28 2 // Header file for class Implementation 3 4 class Implementation { 5 6 public: 7 8 // constructor 9 Implementation( int v ) 10 : value( v ) // initialize value with v 11 { 12 // empty body 13 14 } // end Implementation constructor 15 16 // set value to v 17 void setValue( int v ) 18 { 19 value = v; // should validate v 20 21 } // end function setValue 22 public member function. 23 // return value 24 int getValue() const 25 { 26 return value; 27 28 } // end function getValue 29 30 private: 31 int value; 32 33 }; // end class Implementation
181.
1 // Example29 2 // Header file for interface.cpp 3 4 class Implementation; // forward class declaration 5 6 class Interface { 7 8 public: 9 Interface( int ); 10 void setValue( int ); // same public interface as 11 int getValue() const; // class Implementation 12 ~Interface(); 13 14 private: 15 16 // requires previous forward declaration (line 4) 17 Implementation *ptr; 18 19 }; // end class Interface Provide same public interface as class Implementation; recall setValue and getValue only public member functions. Pointer to Implementation object requires forward class declaration.
182.
1 // Example30 2 // Definition of class Interface 3 #include "interface.h" // Interface class definition 4 #include "implementation.h" // Implementation class definition 5 6 // constructor 7 Interface::Interface( int v ) 8 : ptr ( new Implementation( v ) ) // initialize ptr 9 { 10 // empty body 11 12 } // end Interface constructor 13 14 // call Implementation's setValue function 15 void Interface::setValue( int v ) 16 { 17 ptr->setValue( v ); 18 19 } // end function setValue 20 Proxy class Interface includes header file for class Implementation. Maintain pointer to underlying Implementation object. Invoke corresponding function on underlying Implementation object.
183.
21 // callImplementation's getValue function 22 int Interface::getValue() const 23 { 24 return ptr->getValue(); 25 26 } // end function getValue 27 28 // destructor 29 Interface::~Interface() 30 { 31 delete ptr; 32 33 } // end destructor ~Interface Invoke corresponding function on underlying Implementation object. Deallocate underlying Implementation object.
184.
1 // Example30 2 // Hiding a class’s private data with a proxy class. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include "interface.h" // Interface class definition 9 10 int main() 11 { 12 Interface i( 5 ); 13 14 cout << "Interface contains: " << i.getValue() 15 << " before setValue" << endl; 16 17 i.setValue( 10 ); 18 19 cout << "Interface contains: " << i.getValue() 20 << " after setValue" << endl; 21 22 return 0; 23 24 } // end main Interface contains: 5 before setValue Interface contains: 10 after setValue Only include proxy class header file. Create object of proxy class Interface; note no mention of Implementation class. Invoke member functions via proxy class object.
185.
Fundamentals of Operator Overloading Use operators with objects (operator overloading) Clearer than function calls for certain classes Operator sensitive to context Types Built in (int, char) or user-defined Can use existing operators with user-defined types Cannot create new operators Overloading operators Create a function for the class Name function operator followed by symbol Operator+ for the addition operator +
186.
Fundamentals of Operator Overloading Using operators on a class object It must be overloaded for that class Exceptions: Assignment operator, = May be used without explicit overloading Memberwise assignment between objects Address operator, & May be used on any class without overloading Returns address of object Both can be overloaded
187.
Restrictions on Operator Overloading Cannot change How operators act on built-in data types I.e., cannot change integer addition Precedence of operator (order of evaluation) Use parentheses to force order-of-operations Associativity (left-to-right or right-to-left) Number of operands & is unitary, only acts on one operand Cannot create new operators Operators must be overloaded explicitly Overloading + does not overload +=
188.
Restrictions on Operator Overloading Operatorsthat cannot be overloaded . .* :: ?: sizeof Operators that can be overloaded + - * / % ^ & | ~ ! = < > += -= *= /= %= ^= &= |= << >> >>= <<= == != <= >= && || ++ -- ->* , -> [] () new delete new[] delete[]
189.
Operator Functions AsClass Members Vs. As Friend Functions Operator functions Member functions Use this keyword to implicitly get argument Gets left operand for binary operators (like +) Leftmost object must be of same class as operator Non member functions Need parameters for both operands Can have object of different class than operator Must be a friend to access private or protected data Example Overloaded << operator Left operand of type ostream & Such as cout object in cout << classObject Similarly, overloaded >> needs istream & Thus, both must be non-member functions
190.
Operator Functions AsClass Members Vs. As Friend Functions Commutative operators May want + to be commutative So both “a + b” and “b + a” work Suppose we have two different classes Overloaded operator can only be member function when its class is on left HugeIntClass + Long int Can be member function When other way, need a non-member overload function Long int + HugeIntClass
191.
Overloading Stream-Insertion and Stream-ExtractionOperators << and >> Already overloaded to process each built-in type Can also process a user-defined class Example program Class PhoneNumber Holds a telephone number Print out formatted number automatically (123) 456-7890
192.
1 // Example31 2 // Overloading the stream-insertion and 3 // stream-extraction operators. 4 #include <iostream> 5 6 using std::cout; 7 using std::cin; 8 using std::endl; 9 using std::ostream; 10 using std::istream; 11 12 #include <iomanip> 13 14 using std::setw; 15 16 // PhoneNumber class definition 17 class PhoneNumber { 18 friend ostream &operator<<( ostream&, const PhoneNumber & ); 19 friend istream &operator>>( istream&, PhoneNumber & ); 20 21 private: 22 char areaCode[ 4 ]; // 3-digit area code and null 23 char exchange[ 4 ]; // 3-digit exchange and null 24 char line[ 5 ]; // 4-digit line and null 25 26 }; // end class PhoneNumber Notice function prototypes for overloaded operators >> and << They must be non-member friend functions, since the object of class Phonenumber appears on the right of the operator. cin << object cout >> object
193.
27 28 // overloadedstream-insertion operator; cannot be 29 // a member function if we would like to invoke it with 30 // cout << somePhoneNumber; 31 ostream &operator<<( ostream &output, const PhoneNumber &num ) 32 { 33 output << "(" << num.areaCode << ") " 34 << num.exchange << "-" << num.line; 35 36 return output; // enables cout << a << b << c; 37 38 } // end function operator<< 39 40 // overloaded stream-extraction operator; cannot be 41 // a member function if we would like to invoke it with 42 // cin >> somePhoneNumber; 43 istream &operator>>( istream &input, PhoneNumber &num ) 44 { 45 input.ignore(); // skip ( 46 input >> setw( 4 ) >> num.areaCode; // input area code 47 input.ignore( 2 ); // skip ) and space 48 input >> setw( 4 ) >> num.exchange; // input exchange 49 input.ignore(); // skip dash (-) 50 input >> setw( 5 ) >> num.line; // input line 51 52 return input; // enables cin >> a >> b >> c; The expression: cout << phone; is interpreted as the function call: operator<<(cout, phone); output is an alias for cout. This allows objects to be cascaded. cout << phone1 << phone2; first calls operator<<(cout, phone1), and returns cout. Next, cout << phone2 executes. Stream manipulator setw restricts number of characters read. setw(4) allows 3 characters to be read, leaving room for the null character.
194.
53 54 } //end function operator>> 55 56 int main() 57 { 58 PhoneNumber phone; // create object phone 59 60 cout << "Enter phone number in the form (123) 456-7890:n"; 61 62 // cin >> phone invokes operator>> by implicitly issuing 63 // the non-member function call operator>>( cin, phone ) 64 cin >> phone; 65 66 cout << "The phone number entered was: " ; 67 68 // cout << phone invokes operator<< by implicitly issuing 69 // the non-member function call operator<<( cout, phone ) 70 cout << phone << endl; 71 72 return 0; 73 74 } // end main Enter phone number in the form (123) 456-7890: (800) 555-1212 The phone number entered was: (800) 555-1212
195.
Overloading Unary Operators Overloading unary operators Non-static member function, no arguments Non-member function, one argument Argument must be class object or reference to class object Remember, static functions only access static data
196.
Overloading Operators Overloading unaryoperators (! to test for empty string) Non-static member function: !s becomes s.operator!() bool operator!() const; Non-member function:!s becomes operator!(s) friend bool operator!( const String & ) Overloading binary operators Non-member function (arg. must be class object or reference) friend const String &operator+=(String &, const String & ); Non-static member function: const String &operator+=( const String & ); y += z equivalent to y.operator+=( z )
197.
Case Study: Arrayclass Arrays in C++ No range checking Cannot be compared meaningfully with == No array assignment (array names const pointers) Cannot input/output entire arrays at once Example:Implement an Array class with Range checking Array assignment Arrays that know their size Outputting/inputting entire arrays with << and >> Array comparisons with == and !=
198.
Case Study: Arrayclass Copy constructor Used whenever copy of object needed Passing by value (return value or parameter) Initializing an object with a copy of another Array newArray( oldArray ); newArray copy of oldArray Prototype for class Array Array( const Array & ); Must take reference Otherwise, pass by value Tries to make copy by calling copy constructor… Infinite loop
199.
1 // Example32 2 // Array class for storing arrays of integers. 3 #ifndef ARRAY1_H 4 #define ARRAY1_H 5 6 #include <iostream> 7 8 using std::ostream; 9 using std::istream; 10 11 class Array { 12 friend ostream &operator<<( ostream &, const Array & ); 13 friend istream &operator>>( istream &, Array & ); 14 15 public: 16 Array( int = 10 ); // default constructor 17 Array( const Array & ); // copy constructor 18 ~Array(); // destructor 19 int getSize() const; // return size 20 21 // assignment operator 22 const Array &operator=( const Array & ); 23 24 // equality operator 25 bool operator==( const Array & ) const; 26 Most operators overloaded as member functions (except << and >>, which must be non- member functions). Prototype for copy constructor.
200.
27 // inequalityoperator; returns opposite of == operator 28 bool operator!=( const Array &right ) const 29 { 30 return ! ( *this == right ); // invokes Array::operator== 31 32 } // end function operator!= 33 34 // subscript operator for non-const objects returns lvalue 35 int &operator[]( int ); 36 37 // subscript operator for const objects returns rvalue 38 const int &operator[]( int ) const; 39 40 private: 41 int size; // array size 42 int *ptr; // pointer to first element of array 43 44 }; // end class Array 45 46 #endif != operator simply returns opposite of == operator. Thus, only need to define the == operator.
201.
1 // Example33 2 // Member function definitions for class Array 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 #include <iomanip> 10 11 using std::setw; 12 13 #include <new> // C++ standard "new" operator 14 15 #include <cstdlib> // exit function prototype 16 17 #include "array1.h" // Array class definition 18 19 // default constructor for class Array (default size 10) 20 Array::Array( int arraySize ) 21 { 22 // validate arraySize 23 size = ( arraySize > 0 ? arraySize : 10 ); 24 25 ptr = new int[ size ]; // create space for array 26
202.
27 for (int i = 0; i < size; i++ ) 28 ptr[ i ] = 0; // initialize array 29 30 } // end Array default constructor 31 32 // copy constructor for class Array; 33 // must receive a reference to prevent infinite recursion 34 Array::Array( const Array &arrayToCopy ) 35 : size( arrayToCopy.size ) 36 { 37 ptr = new int[ size ]; // create space for array 38 39 for ( int i = 0; i < size; i++ ) 40 ptr[ i ] = arrayToCopy.ptr[ i ]; // copy into object 41 42 } // end Array copy constructor 43 44 // destructor for class Array 45 Array::~Array() 46 { 47 delete [] ptr; // reclaim array space 48 49 } // end destructor 50 We must declare a new integer array so the objects do not point to the same memory.
203.
51 // returnsize of array 52 int Array::getSize() const 53 { 54 return size; 55 56 } // end function getSize 57 58 // overloaded assignment operator; 59 // const return avoids: ( a1 = a2 ) = a3 60 const Array &Array::operator=( const Array &right ) 61 { 62 if ( &right != this ) { // check for self-assignment 63 64 // for arrays of different sizes, deallocate original 65 // left-side array, then allocate new left-side array 66 if ( size != right.size ) { 67 delete [] ptr; // reclaim space 68 size = right.size; // resize this object 69 ptr = new int[ size ]; // create space for array copy 70 71 } // end inner if 72 73 for ( int i = 0; i < size; i++ ) 74 ptr[ i ] = right.ptr[ i ]; // copy array into object 75 76 } // end outer if Want to avoid self-assignment.
204.
77 78 return *this;// enables x = y = z, for example 79 80 } // end function operator= 81 82 // determine if two arrays are equal and 83 // return true, otherwise return false 84 bool Array::operator==( const Array &right ) const 85 { 86 if ( size != right.size ) 87 return false; // arrays of different sizes 88 89 for ( int i = 0; i < size; i++ ) 90 91 if ( ptr[ i ] != right.ptr[ i ] ) 92 return false; // arrays are not equal 93 94 return true; // arrays are equal 95 96 } // end function operator== 97
205.
98 // overloadedsubscript operator for non-const Arrays 99 // reference return creates an lvalue 100 int &Array::operator[]( int subscript ) 101 { 102 // check for subscript out of range error 103 if ( subscript < 0 || subscript >= size ) { 104 cout << "nError: Subscript " << subscript 105 << " out of range" << endl; 106 107 exit( 1 ); // terminate program; subscript out of range 108 109 } // end if 110 111 return ptr[ subscript ]; // reference return 112 113 } // end function operator[] 114 integers1[5] calls integers1.operator[]( 5 ) exit() (header <cstdlib>) ends the program.
206.
115 // overloadedsubscript operator for const Arrays 116 // const reference return creates an rvalue 117 const int &Array::operator[]( int subscript ) const 118 { 119 // check for subscript out of range error 120 if ( subscript < 0 || subscript >= size ) { 121 cout << "nError: Subscript " << subscript 122 << " out of range" << endl; 123 124 exit( 1 ); // terminate program; subscript out of range 125 126 } // end if 127 128 return ptr[ subscript ]; // const reference return 129 130 } // end function operator[] 131 132 // overloaded input operator for class Array; 133 // inputs values for entire array 134 istream &operator>>( istream &input, Array &a ) 135 { 136 for ( int i = 0; i < a.size; i++ ) 137 input >> a.ptr[ i ]; 138 139 return input; // enables cin >> x >> y; 140 141 } // end function
207.
142 143 // overloadedoutput operator for class Array 144 ostream &operator<<( ostream &output, const Array &a ) 145 { 146 int i; 147 148 // output private ptr-based array 149 for ( i = 0; i < a.size; i++ ) { 150 output << setw( 12 ) << a.ptr[ i ]; 151 152 if ( ( i + 1 ) % 4 == 0 ) // 4 numbers per row of output 153 output << endl; 154 155 } // end for 156 157 if ( i % 4 != 0 ) // end last line of output 158 output << endl; 159 160 return output; // enables cout << x << y; 161 162 } // end function operator<<
208.
Converting between Types Cast operator (conversion operator) Convert from One class to another built-in type Must be non-static member function - Cannot be friend Do not specify return type Implicitly returns type to which you are converting Example: A::operator char *() const; Casts class A to a temporary char * (char *)s calls s.operator char*() A::operator int() const; A::operator OtherClass() const; Casting can prevent need for overloading Suppose class String can be cast to char * cout << s; // cout expects char *; s is a String Compiler implicitly calls the function to convert s to char * Do not have to overload << for String
209.
Case Study: AString Class Build class String String creation, manipulation Class string in standard library (more Chapter 15) Conversion constructor Single-argument constructor Turns objects of other types into class objects String s1(“hi”); Creates a String from a char * Any single-argument constructor is a conversion constructor
210.
Overloading ++ and-- Increment/decrement operators can be overloaded Add 1 to a Date object, d1 Prototype (member function) Date &operator++(); ++d1 same as d1.operator++() Prototype (non-member) Friend Date &operator++( Date &); ++d1 same as operator++( d1 )
211.
Overloading ++ and-- To distinguish pre/post increment Post increment has a dummy parameter int of 0 Prototype (member function) Date operator++( int ); d1++ same as d1.operator++( 0 ) Prototype (non-member) friend Date operator++( Data &, int ); d1++ same as operator++( d1, 0 ) Integer parameter does not have a name Not even in function definition
212.
Overloading ++ and-- Return values Preincrement Returns by reference (Date &) lvalue (can be assigned) Postincrement Returns by value Returns temporary object with old value rvalue (cannot be on left side of assignment) Example Date class Overloaded increment operator Change day, month and year Overloaded += operator Function to test for leap years Function to determine if day is last of month
213.
1 // Example34 2 // Date class definition. 3 #ifndef DATE1_H 4 #define DATE1_H 5 #include <iostream> 6 7 using std::ostream; 8 9 class Date { 10 friend ostream &operator<<( ostream &, const Date & ); 11 12 public: 13 Date( int m = 1, int d = 1, int y = 1900 ); // constructor 14 void setDate( int, int, int ); // set the date 15 16 Date &operator++(); // preincrement operator 17 Date operator++( int ); // postincrement operator 18 19 const Date &operator+=( int ); // add days, modify object 20 21 bool leapYear( int ) const; // is this a leap year? 22 bool endOfMonth( int ) const; // is this end of month? Note difference between pre and post increment.
214.
23 24 private: 25 intmonth; 26 int day; 27 int year; 28 29 static const int days[]; // array of days per month 30 void helpIncrement(); // utility function 31 32 }; // end class Date 33 34 #endif 35 Date &Date::operator++() 36 { 37 helpIncrement(); 37 return *this; // reference return to create an lvalue 39 } // end function operator++ 40 41 // overloaded postincrement operator; note that the dummy 42 // integer parameter does not have a parameter name 43 Date Date::operator++( int ) 44 { 45 Date temp = *this; // hold current state of object 46 helpIncrement(); 48 // return unincremented, saved, temporary object 49 return temp; // value return; not a reference return 51 } // end function operator++
215.
Inheritance Inheritance Softwarereusability Create new class from existing class Absorb existing class’s data and behaviors Enhance with new capabilities Derived class inherits from base class Derived class More specialized group of objects Behaviors inherited from base class Can customize Additional behaviors
216.
Inheritance Class hierarchy Direct base class Inherited explicitly (one level up hierarchy) Indirect base class Inherited two or more levels up hierarchy Single inheritance Inherits from one base class Multiple inheritance Inherits from multiple base classes Base classes possibly unrelated Chapter 22
217.
Inheritance Three typesof inheritance public Every object of derived class also object of base class Base-class objects not objects of derived classes Example: All cars vehicles, but not all vehicles cars Can access non-private members of base class Derived class can effect change to private base-class members Through inherited non-private member functions private Alternative to composition Chapter 17 protected Rarely used
218.
Inheritance Abstraction Focuson commonalities among objects in system “is-a” vs. “has-a” “is-a” Inheritance Derived class object treated as base class object Example: Car is a vehicle Vehicle properties/behaviors also car properties/behaviors “has-a” Composition Object contains one or more objects of other classes as members Example: Car has a steering wheel
219.
Base Classes andDerived Classes Base classes and derived classes Object of one class “is an” object of another class Example: Rectangle is quadrilateral. Base class typically represents larger set of objects than derived classes Example: Base class: Vehicle Cars, trucks, boats, bicycles, … Derived class: Car Smaller, more-specific subset of vehicles
220.
Base Classes andDerived Classes Inheritance examples Base class Derived classes Student GraduateStudent UndergraduateStudent Shape Circle Triangle Rectangle Loan CarLoan HomeImprovementLoan MortgageLoan Employee FacultyMember StaffMember Account CheckingAccount SavingsAccount
221.
Base Classes andDerived Classes Inheritance hierarchy Inheritance relationships: tree-like hierarchy structure Each class becomes Base class Supply data/behaviors to other classes OR Derived class Inherit data/behaviors from other classes
Base Classes andDerived Classes public inheritance Specify with: Class TwoDimensionalShape : public Shape Class TwoDimensionalShape inherits from class Shape Base class private members Not accessible directly Still inherited - manipulate through inherited member functions Base class public and protected members Inherited with original member access friend functions Not inherited
225.
protected Members protectedaccess Intermediate level of protection between public and private protected members accessible to Base class members Base class friends Derived class members Derived class friends Derived-class members Refer to public and protected members of base class Simply use member names
226.
Relationship between BaseClasses and Derived Classes Base class and derived class relationship Example: Point/circle inheritance hierarchy Point x-y coordinate pair Circle x-y coordinate pair Radius
227.
Relationship between BaseClasses and Derived Classes Using protected data members Advantages Derived classes can modify values directly Slight increase in performance Avoid set/get function call overhead Disadvantages No validity checking Derived class can assign illegal value Implementation dependent Derived class member functions more likely dependent on base class implementation Base class implementation changes may result in derived class modifications Fragile (brittle) software
228.
Case Study: Three-LevelInheritance Hierarchy Three level point/circle/cylinder hierarchy Point x-y coordinate pair Circle x-y coordinate pair Radius Cylinder x-y coordinate pair Radius Height
229.
Constructors and Destructorsin Derived Classes Instantiating derived-class object Chain of constructor calls Derived-class constructor invokes base class constructor Implicitly or explicitly Base of inheritance hierarchy Last constructor called in chain First constructor body to finish executing Example: Point3/Circle4/Cylinder hierarchy Point3 constructor called last Point3 constructor body finishes execution first Initializing data members Each base-class constructor initializes data members inherited by derived class
230.
Constructors and Destructorsin Derived Classes Destroying derived-class object Chain of destructor calls Reverse order of constructor chain Destructor of derived-class called first Destructor of next base class up hierarchy next Continue up hierarchy until final base reached After final base-class destructor, object removed from memory Base-class constructors, destructors, assignment operators Not inherited by derived classes Derived class constructors, assignment operators can call Constructors Assignment operators
231.
public, protected andprivate Inheritance Type of inheritanceBase class member access specifier public inheritance protected inheritance private inheritance Public public in derived class. Can be accessed directly by any non-static member functions, friend functions and non- member functions. protected in derived class. Can be accessed directly by all non-static member functions and friend functions. private in derived class. Can be accessed directly by all non-static member functions and friend functions. Protected protected in derived class. Can be accessed directly by all non-static member functions and friend functions. protected in derived class. Can be accessed directly by all non-static member functions and friend functions. private in derived class. Can be accessed directly by all non-static member functions and friend functions. Private Hidden in derived class. Can be accessed by non-static member functions and friend functions through public or protected member functions of the base class. Hidden in derived class. Can be accessed by non-static member functions and friend functions through public or protected member functions of the base class. Hidden in derived class. Can be accessed by non-static member functions and friend functions through public or protected member functions of the base class.
232.
1 // Example35 2 // Point class definition represents an x-y coordinate pair. 3 #ifndef POINT_H 4 #define POINT_H 5 6 class Point { 7 8 public: 9 Point( int = 0, int = 0 ); // default constructor 10 11 void setX( int ); // set x in coordinate pair 12 int getX() const; // return x from coordinate pair 13 14 void setY( int ); // set y in coordinate pair 15 int getY() const; // return y from coordinate pair 16 17 void print() const; // output Point object 18 19 private: 20 int x; // x part of coordinate pair 21 int y; // y part of coordinate pair 22 23 }; // end class Point 24 25 #endif Maintain x- and y- coordinates as private data members.
233.
1 // Example36 2 // Circle2 class contains x-y coordinate pair and radius. 3 #ifndef CIRCLE2_H 4 #define CIRCLE2_H 5 6 #include "point.h" // Point class definition 7 8 class Circle2 : public Point { 9 10 public: 11 12 // default constructor 13 Circle2( int = 0, int = 0, double = 0.0 ); 14 15 void setRadius( double ); // set radius 16 double getRadius() const; // return radius 17 18 double getDiameter() const; // return diameter 19 double getCircumference() const; // return circumference 20 double getArea() const; // return area 21 22 void print() const; // output Circle2 object 23 24 private: 25 double radius; // Circle2's radius Class Circle2 inherits from class Point. Maintain private data member radius. Colon indicates inheritance.Keyword public indicates type of inheritance.
234.
26 27 }; //end class Circle2 28 29 #endif 1 // Fig. 9.11: circle2.cpp 2 // Circle2 class member-function definitions. 3 #include <iostream> 4 5 using std::cout; 6 7 #include "circle2.h" // Circle2 class definition 8 9 // default constructor 10 Circle2::Circle2( int xValue, int yValue, double radiusValue ) 11 { 12 x = xValue; 13 y = yValue; 14 setRadius( radiusValue ); 15 16 } // end Circle2 constructor 17 Attempting to access base class Point’s private data members x and y results in syntax errors.
39 // calculateand return circumference 40 double Circle2::getCircumference() const 41 { 42 return 3.14159 * getDiameter(); 43 44 } // end function getCircumference 45 46 // calculate and return area 47 double Circle2::getArea() const 48 { 49 return 3.14159 * radius * radius; 50 51 } // end function getArea 52 53 // output Circle2 object 54 void Circle2::print() const 55 { 56 cout << "Center = [" << x << ", " << y << ']' 57 << "; Radius = " << radius; 58 59 } // end function print Attempting to access base class Point’s private data members x and y results in syntax errors.
237.
1 // Example37 2 // Point class definition represents an x-y coordinate pair. 3 #ifndef POINT_H 4 #define POINT_H 5 6 class Point { 7 8 public: 9 Point( int = 0, int = 0 ); // default constructor 10 11 void setX( int ); // set x in coordinate pair 12 int getX() const; // return x from coordinate pair 13 14 void setY( int ); // set y in coordinate pair 15 int getY() const; // return y from coordinate pair 16 17 void print() const; // output Point object 18 19 private: 20 int x; // x part of coordinate pair 21 int y; // y part of coordinate pair 22 23 }; // end class Point 24 25 #endif Maintain x- and y- coordinates as private data members.
238.
1 // Example38 2 // Point class member-function definitions. 3 #include <iostream> 4 5 using std::cout; 6 7 #include "point.h" // Point class definition 8 9 // default constructor 10 Point::Point( int xValue, int yValue ) 11 { 12 x = xValue; 13 y = yValue; 14 15 } // end Point constructor 16 17 // set x in coordinate pair 18 void Point::setX( int xValue ) 19 { 20 x = xValue; // no need for validation 21 22 } // end function setX 23
239.
24 // returnx from coordinate pair 25 int Point::getX() const 26 { 27 return x; 28 29 } // end function getX 30 31 // set y in coordinate pair 32 void Point::setY( int yValue ) 33 { 34 y = yValue; // no need for validation 35 36 } // end function setY 37 38 // return y from coordinate pair 39 int Point::getY() const 40 { 41 return y; 42 43 } // end function getY 44
240.
45 // outputPoint object 46 void Point::print() const 47 { 48 cout << '[' << x << ", " << y << ']'; 49 50 } // end function print
241.
1 // Example39 2 // Testing class Point. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include "point.h" // Point class definition 9 10 int main() 11 { 12 Point point( 72, 115 ); // instantiate Point object 13 14 // display point coordinates 15 cout << "X coordinate is " << point.getX() 16 << "nY coordinate is " << point.getY(); 17 18 point.setX( 10 ); // set x-coordinate 19 point.setY( 10 ); // set y-coordinate 20 21 // display new point value 22 cout << "nnThe new location of point is "; 23 point.print(); 24 cout << endl; 25 Create a Point object. Invoke set functions to modify private data. Invoke public function print to display new coordinates.
242.
26 return 0;// indicates successful termination 27 28 } // end main X coordinate is 72 Y coordinate is 115 The new location of point is [10, 10]
243.
1 // Example40 2 // Circle class contains x-y coordinate pair and radius. 3 #ifndef CIRCLE_H 4 #define CIRCLE_H 5 6 class Circle { 7 8 public: 9 10 // default constructor 11 Circle( int = 0, int = 0, double = 0.0 ); 12 13 void setX( int ); // set x in coordinate pair 14 int getX() const; // return x from coordinate pair 15 16 void setY( int ); // set y in coordinate pair 17 int getY() const; // return y from coordinate pair 18 19 void setRadius( double ); // set radius 20 double getRadius() const; // return radius 21 22 double getDiameter() const; // return diameter 23 double getCircumference() const; // return circumference 24 double getArea() const; // return area 25 Note code similar to Point code.
244.
26 void print()const; // output Circle object 27 28 private: 29 int x; // x-coordinate of Circle's center 30 int y; // y-coordinate of Circle's center 31 double radius; // Circle's radius 32 33 }; // end class Circle 34 35 #endif Maintain x-y coordinates and radius as private data members. Note code similar to Point code.
245.
1 // Example41 2 // Circle class member-function definitions. 3 #include <iostream> 4 5 using std::cout; 6 7 #include "circle.h" // Circle class definition 8 9 // default constructor 10 Circle::Circle( int xValue, int yValue, double radiusValue ) 11 { 12 x = xValue; 13 y = yValue; 14 setRadius( radiusValue ); 15 16 } // end Circle constructor 17 18 // set x in coordinate pair 19 void Circle::setX( int xValue ) 20 { 21 x = xValue; // no need for validation 22 23 } // end function setX 24
246.
25 // returnx from coordinate pair 26 int Circle::getX() const 27 { 28 return x; 29 30 } // end function getX 31 32 // set y in coordinate pair 33 void Circle::setY( int yValue ) 34 { 35 y = yValue; // no need for validation 36 37 } // end function setY 38 39 // return y from coordinate pair 40 int Circle::getY() const 41 { 42 return y; 43 44 } // end function getY 45
247.
46 // setradius 47 void Circle::setRadius( double radiusValue ) 48 { 49 radius = ( radiusValue < 0.0 ? 0.0 : radiusValue ); 50 51 } // end function setRadius 52 53 // return radius 54 double Circle::getRadius() const 55 { 56 return radius; 57 58 } // end function getRadius 59 60 // calculate and return diameter 61 double Circle::getDiameter() const 62 { 63 return 2 * radius; 64 65 } // end function getDiameter 66 Ensure non-negative value for radius.
248.
67 // calculateand return circumference 68 double Circle::getCircumference() const 69 { 70 return 3.14159 * getDiameter(); 71 72 } // end function getCircumference 73 74 // calculate and return area 75 double Circle::getArea() const 76 { 77 return 3.14159 * radius * radius; 78 79 } // end function getArea 80 81 // output Circle object 82 void Circle::print() const 83 { 84 cout << "Center = [" << x << ", " << y << ']' 85 << "; Radius = " << radius; 86 87 } // end function print
249.
1 // Example42 2 // Testing class Circle. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 using std::fixed; 8 9 #include <iomanip> 10 11 using std::setprecision; 12 13 #include "circle.h" // Circle class definition 14 15 int main() 16 { 17 Circle circle( 37, 43, 2.5 ); // instantiate Circle object 18 19 // display point coordinates 20 cout << "X coordinate is " << circle.getX() 21 << "nY coordinate is " << circle.getY() 22 << "nRadius is " << circle.getRadius(); 23 Create Circle object.
250.
24 circle.setX( 2); // set new x-coordinate 25 circle.setY( 2 ); // set new y-coordinate 26 circle.setRadius( 4.25 ); // set new radius 27 28 // display new point value 29 cout << "nnThe new location and radius of circle aren"; 30 circle.print(); 31 32 // display floating-point values with 2 digits of precision 33 cout << fixed << setprecision( 2 ); 34 35 // display Circle's diameter 36 cout << "nDiameter is " << circle.getDiameter(); 37 38 // display Circle's circumference 39 cout << "nCircumference is " << circle.getCircumference(); 40 41 // display Circle's area 42 cout << "nArea is " << circle.getArea(); 43 44 cout << endl; 45 46 return 0; // indicates successful termination 47 48 } // end main Use set functions to modify private data. Invoke public function print to display new coordinates.
251.
X coordinate is37 Y coordinate is 43 Radius is 2.5 The new location and radius of circle are Center = [2, 2]; Radius = 4.25 Diameter is 8.50 Circumference is 26.70 Area is 56.74
252.
1 // Example43 2 // Circle2 class contains x-y coordinate pair and radius. 3 #ifndef CIRCLE2_H 4 #define CIRCLE2_H 5 6 #include "point.h" // Point class definition 7 8 class Circle2 : public Point { 9 10 public: 11 12 // default constructor 13 Circle2( int = 0, int = 0, double = 0.0 ); 14 15 void setRadius( double ); // set radius 16 double getRadius() const; // return radius 17 18 double getDiameter() const; // return diameter 19 double getCircumference() const; // return circumference 20 double getArea() const; // return area 21 22 void print() const; // output Circle2 object 23 24 private: 25 double radius; // Circle2's radius Class Circle2 inherits from class Point. Maintain private data member radius. Colon indicates inheritance.Keyword public indicates type of inheritance.
253.
26 27 }; //end class Circle2 28 29 #endif 1 // Fig. 9.11: circle2.cpp 2 // Circle2 class member-function definitions. 3 #include <iostream> 4 5 using std::cout; 6 7 #include "circle2.h" // Circle2 class definition 8 9 // default constructor 10 Circle2::Circle2( int xValue, int yValue, double radiusValue ) 11 { 12 x = xValue; 13 y = yValue; 14 setRadius( radiusValue ); 15 16 } // end Circle2 constructor 17 Attempting to access base class Point’s private data members x and y results in syntax errors.
39 // calculateand return circumference 40 double Circle2::getCircumference() const 41 { 42 return 3.14159 * getDiameter(); 43 44 } // end function getCircumference 45 46 // calculate and return area 47 double Circle2::getArea() const 48 { 49 return 3.14159 * radius * radius; 50 51 } // end function getArea 52 53 // output Circle2 object 54 void Circle2::print() const 55 { 56 cout << "Center = [" << x << ", " << y << ']' 57 << "; Radius = " << radius; 58 59 } // end function print Attempting to access base class Point’s private data members x and y results in syntax errors.
256.
C:cpphtp4examplesch09CircleTestcircle2.cpp(12) : errorC2248: 'x' : cannot access private member declared in class 'Point' C:cpphtp4examplesch09circletestpoint.h(20) : see declaration of 'x' C:cpphtp4examplesch09CircleTestcircle2.cpp(13) : error C2248: 'y' : cannot access private member declared in class 'Point' C:cpphtp4examplesch09circletestpoint.h(21) : see declaration of 'y' C:cpphtp4examplesch09CircleTestcircle2.cpp(56) : error C2248: 'x' : cannot access private member declared in class 'Point' C:cpphtp4examplesch09circletestpoint.h(20) : see declaration of 'x' C:cpphtp4examplesch09CircleTestcircle2.cpp(56) : error C2248: 'y' : cannot access private member declared in class 'Point' C:cpphtp4examplesch09circletestpoint.h(21) : see declaration of 'y' Attempting to access base class Point’s private data members x and y results in syntax errors.
257.
1 // Example44 2 // Point2 class definition represents an x-y coordinate pair. 3 #ifndef POINT2_H 4 #define POINT2_H 5 6 class Point2 { 7 8 public: 9 Point2( int = 0, int = 0 ); // default constructor 10 11 void setX( int ); // set x in coordinate pair 12 int getX() const; // return x from coordinate pair 13 14 void setY( int ); // set y in coordinate pair 15 int getY() const; // return y from coordinate pair 16 17 void print() const; // output Point2 object 18 19 protected: 20 int x; // x part of coordinate pair 21 int y; // y part of coordinate pair 22 23 }; // end class Point2 24 25 #endif Maintain x- and y- coordinates as protected data, accessible to derived classes.
258.
1 // Example45 2 // Point2 class member-function definitions. 3 #include <iostream> 4 5 using std::cout; 6 7 #include "point2.h" // Point2 class definition 8 9 // default constructor 10 Point2::Point2( int xValue, int yValue ) 11 { 12 x = xValue; 13 y = yValue; 14 15 } // end Point2 constructor 16 17 // set x in coordinate pair 18 void Point2::setX( int xValue ) 19 { 20 x = xValue; // no need for validation 21 22 } // end function setX 23
259.
24 // returnx from coordinate pair 25 int Point2::getX() const 26 { 27 return x; 28 29 } // end function getX 30 31 // set y in coordinate pair 32 void Point2::setY( int yValue ) 33 { 34 y = yValue; // no need for validation 35 36 } // end function setY 37 38 // return y from coordinate pair 39 int Point2::getY() const 40 { 41 return y; 42 43 } // end function getY 44
260.
45 // outputPoint2 object 46 void Point2::print() const 47 { 48 cout << '[' << x << ", " << y << ']'; 49 50 } // end function print
261.
1 // Example46 2 // Circle3 class contains x-y coordinate pair and radius. 3 #ifndef CIRCLE3_H 4 #define CIRCLE3_H 5 6 #include "point2.h" // Point2 class definition 7 8 class Circle3 : public Point2 { 9 10 public: 11 12 // default constructor 13 Circle3( int = 0, int = 0, double = 0.0 ); 14 15 void setRadius( double ); // set radius 16 double getRadius() const; // return radius 17 18 double getDiameter() const; // return diameter 19 double getCircumference() const; // return circumference 20 double getArea() const; // return area 21 22 void print() const; // output Circle3 object 23 24 private: 25 double radius; // Circle3's radius Class Circle3 inherits from class Point2. Maintain private data member radius.
1 // Example47 2 // Circle3 class member-function definitions. 3 #include <iostream> 4 5 using std::cout; 6 7 #include "circle3.h" // Circle3 class definition 8 9 // default constructor 10 Circle3::Circle3( int xValue, int yValue, double radiusValue ) 11 { 12 x = xValue; 13 y = yValue; 14 setRadius( radiusValue ); 15 16 } // end Circle3 constructor 17 18 // set radius 19 void Circle3::setRadius( double radiusValue ) 20 { 21 radius = ( radiusValue < 0.0 ? 0.0 : radiusValue ); 22 23 } // end function setRadius 24 Modify inherited data members x and y, declared protected in base class Point2. Constructor first implicitly calls base class’s default constructor.
264.
25 // returnradius 26 double Circle3::getRadius() const 27 { 28 return radius; 29 30 } // end function getRadius 31 32 // calculate and return diameter 33 double Circle3::getDiameter() const 34 { 35 return 2 * radius; 36 37 } // end function getDiameter 38 39 // calculate and return circumference 40 double Circle3::getCircumference() const 41 { 42 return 3.14159 * getDiameter(); 43 44 } // end function getCircumference 45
265.
46 // calculateand return area 47 double Circle3::getArea() const 48 { 49 return 3.14159 * radius * radius; 50 51 } // end function getArea 52 53 // output Circle3 object 54 void Circle3::print() const 55 { 56 cout << "Center = [" << x << ", " << y << ']' 57 << "; Radius = " << radius; 58 59 } // end function print Access inherited data members x and y, declared protected in base class Point2.
266.
1 // Example48 2 // Testing class Circle3. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 using std::fixed; 8 9 #include <iomanip> 10 11 using std::setprecision; 12 13 #include "circle3.h" // Circle3 class definition 14 15 int main() 16 { 17 Circle3 circle( 37, 43, 2.5 ); // instantiate Circle3 object 18 19 // display point coordinates 20 cout << "X coordinate is " << circle.getX() 21 << "nY coordinate is " << circle.getY() 22 << "nRadius is " << circle.getRadius(); 23 Use inherited get functions to access inherited protected data x and y. Create Circle3 object. Use Circle3 get function to access private data radius.
267.
24 circle.setX( 2); // set new x-coordinate 25 circle.setY( 2 ); // set new y-coordinate 26 circle.setRadius( 4.25 ); // set new radius 27 28 // display new point value 29 cout << "nnThe new location and radius of circle aren"; 30 circle.print(); 31 32 // display floating-point values with 2 digits of precision 33 cout << fixed << setprecision( 2 ); 34 35 // display Circle3's diameter 36 cout << "nDiameter is " << circle.getDiameter(); 37 38 // display Circle3's circumference 39 cout << "nCircumference is " << circle.getCircumference(); 40 41 // display Circle3's area 42 cout << "nArea is " << circle.getArea(); 43 44 cout << endl; 45 46 return 0; // indicates successful termination 47 48 } // end main Use inherited set functions to modify inherited protected data x and y. Use Circle3 set function to modify private data radius.
268.
X coordinate is37 Y coordinate is 43 Radius is 2.5 The new location and radius of circle are Center = [2, 2]; Radius = 4.25 Diameter is 8.50 Circumference is 26.70 Area is 56.74
269.
Relationship between BaseClasses and Derived Classes Using protected data members Advantages Derived classes can modify values directly Slight increase in performance Avoid set/get function call overhead Disadvantages No validity checking Derived class can assign illegal value Implementation dependent Derived class member functions more likely dependent on base class implementation Base class implementation changes may result in derived class modifications Fragile (brittle) software
270.
1 // Example49 2 // Point3 class definition represents an x-y coordinate pair. 3 #ifndef POINT3_H 4 #define POINT3_H 5 6 class Point3 { 7 8 public: 9 Point3( int = 0, int = 0 ); // default constructor 10 11 void setX( int ); // set x in coordinate pair 12 int getX() const; // return x from coordinate pair 13 14 void setY( int ); // set y in coordinate pair 15 int getY() const; // return y from coordinate pair 16 17 void print() const; // output Point3 object 18 19 private: 20 int x; // x part of coordinate pair 21 int y; // y part of coordinate pair 22 23 }; // end class Point3 24 25 #endif Better software-engineering practice: private over protected when possible.
271.
1 // Example50 2 // Point3 class member-function definitions. 3 #include <iostream> 4 5 using std::cout; 6 7 #include "point3.h" // Point3 class definition 8 9 // default constructor 10 Point3::Point3( int xValue, int yValue ) 11 : x( xValue ), y( yValue ) 12 { 13 // empty body 14 15 } // end Point3 constructor 16 17 // set x in coordinate pair 18 void Point3::setX( int xValue ) 19 { 20 x = xValue; // no need for validation 21 22 } // end function setX 23 Member initializers specify values of x and y.
272.
24 // returnx from coordinate pair 25 int Point3::getX() const 26 { 27 return x; 28 29 } // end function getX 30 31 // set y in coordinate pair 32 void Point3::setY( int yValue ) 33 { 34 y = yValue; // no need for validation 35 36 } // end function setY 37 38 // return y from coordinate pair 39 int Point3::getY() const 40 { 41 return y; 42 43 } // end function getY 44
273.
45 // outputPoint3 object 46 void Point3::print() const 47 { 48 cout << '[' << getX() << ", " << getY() << ']'; 49 50 } // end function print Invoke non-private member functions to access private data.
274.
1 // Example51 2 // Circle4 class contains x-y coordinate pair and radius. 3 #ifndef CIRCLE4_H 4 #define CIRCLE4_H 5 6 #include "point3.h" // Point3 class definition 7 8 class Circle4 : public Point3 { 9 10 public: 11 12 // default constructor 13 Circle4( int = 0, int = 0, double = 0.0 ); 14 15 void setRadius( double ); // set radius 16 double getRadius() const; // return radius 17 18 double getDiameter() const; // return diameter 19 double getCircumference() const; // return circumference 20 double getArea() const; // return area 21 22 void print() const; // output Circle4 object 23 24 private: 25 double radius; // Circle4's radius Class Circle4 inherits from class Point3. Maintain private data member radius.
1 // Example52 2 // Circle4 class member-function definitions. 3 #include <iostream> 4 5 using std::cout; 6 7 #include "circle4.h" // Circle4 class definition 8 9 // default constructor 10 Circle4::Circle4( int xValue, int yValue, double radiusValue ) 11 : Point3( xValue, yValue ) // call base-class constructor 12 { 13 setRadius( radiusValue ); 14 15 } // end Circle4 constructor 16 17 // set radius 18 void Circle4::setRadius( double radiusValue ) 19 { 20 radius = ( radiusValue < 0.0 ? 0.0 : radiusValue ); 21 22 } // end function setRadius 23 Base-class initializer syntax passes arguments to base class Point3.
277.
24 // returnradius 25 double Circle4::getRadius() const 26 { 27 return radius; 28 29 } // end function getRadius 30 31 // calculate and return diameter 32 double Circle4::getDiameter() const 33 { 34 return 2 * getRadius(); 35 36 } // end function getDiameter 37 38 // calculate and return circumference 39 double Circle4::getCircumference() const 40 { 41 return 3.14159 * getDiameter(); 42 43 } // end function getCircumference 44 Invoke function getRadius rather than directly accessing data member radius.
278.
45 // calculateand return area 46 double Circle4::getArea() const 47 { 48 return 3.14159 * getRadius() * getRadius(); 49 50 } // end function getArea 51 52 // output Circle4 object 53 void Circle4::print() const 54 { 55 cout << "Center = "; 56 Point3::print(); // invoke Point3's print function 57 cout << "; Radius = " << getRadius(); 58 59 } // end function print Invoke function getRadius rather than directly accessing data member radius. Redefine class Point3’s member function print. Invoke base-class Point3’s print function using binary scope-resolution operator (::).
279.
1 // Example53 2 // Testing class Circle4. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 using std::fixed; 8 9 #include <iomanip> 10 11 using std::setprecision; 12 13 #include "circle4.h" // Circle4 class definition 14 15 int main() 16 { 17 Circle4 circle( 37, 43, 2.5 ); // instantiate Circle4 object 18 19 // display point coordinates 20 cout << "X coordinate is " << circle.getX() 21 << "nY coordinate is " << circle.getY() 22 << "nRadius is " << circle.getRadius(); 23 Create Circle4 object. Use inherited get functions to access inherited protected data x and y. Use Circle3 get function to access private data radius.
280.
24 circle.setX( 2); // set new x-coordinate 25 circle.setY( 2 ); // set new y-coordinate 26 circle.setRadius( 4.25 ); // set new radius 27 28 // display new circle value 29 cout << "nnThe new location and radius of circle aren"; 30 circle.print(); 31 32 // display floating-point values with 2 digits of precision 33 cout << fixed << setprecision( 2 ); 34 35 // display Circle4's diameter 36 cout << "nDiameter is " << circle.getDiameter(); 37 38 // display Circle4's circumference 39 cout << "nCircumference is " << circle.getCircumference(); 40 41 // display Circle4's area 42 cout << "nArea is " << circle.getArea(); 43 44 cout << endl; 45 46 return 0; // indicates successful termination 47 48 } // end main Use inherited set functions to modify inherited protected data x and y.Use Circle3 set function to modify private data radius.
281.
X coordinate is37 Y coordinate is 43 Radius is 2.5 The new location and radius of circle are Center = [2, 2]; Radius = 4.25 Diameter is 8.50 Circumference is 26.70 Area is 56.74
282.
Case Study: Three-LevelInheritance Hierarchy Three level point/circle/cylinder hierarchy Point x-y coordinate pair Circle x-y coordinate pair Radius Cylinder x-y coordinate pair Radius Height
283.
1 // Example54 2 // Cylinder class inherits from class Circle4. 3 #ifndef CYLINDER_H 4 #define CYLINDER_H 5 6 #include "circle4.h" // Circle4 class definition 7 8 class Cylinder : public Circle4 { 9 10 public: 11 12 // default constructor 13 Cylinder( int = 0, int = 0, double = 0.0, double = 0.0 ); 14 15 void setHeight( double ); // set Cylinder's height 16 double getHeight() const; // return Cylinder's height 17 18 double getArea() const; // return Cylinder's area 19 double getVolume() const; // return Cylinder's volume 20 void print() const; // output Cylinder 21 22 private: 23 double height; // Cylinder's height 24 25 }; // end class Cylinder Class Cylinder inherits from class Circle4. Maintain private data member height.
284.
26 27 #endif 1 //Fig. 9.23: cylinder.cpp 2 // Cylinder class inherits from class Circle4. 3 #include <iostream> 4 5 using std::cout; 6 7 #include "cylinder.h" // Cylinder class definition 8 9 // default constructor 10 Cylinder::Cylinder( int xValue, int yValue, double radiusValue, 11 double heightValue ) 12 : Circle4( xValue, yValue, radiusValue ) 13 { 14 setHeight( heightValue ); 15 16 } // end Cylinder constructor 17 Base-class initializer syntax passes arguments to base class Circle4.
285.
18 // setCylinder's height 19 void Cylinder::setHeight( double heightValue ) 20 { 21 height = ( heightValue < 0.0 ? 0.0 : heightValue ); 22 23 } // end function setHeight 24 25 // get Cylinder's height 26 double Cylinder::getHeight() const 27 { 28 return height; 29 30 } // end function getHeight 31 32 // redefine Circle4 function getArea to calculate Cylinder area 33 double Cylinder::getArea() const 34 { 35 return 2 * Circle4::getArea() + 36 getCircumference() * getHeight(); 37 38 } // end function getArea 39 Redefine base class Circle4’s member function getArea to return Cylinder surface area. Invoke base-class Circle4’s getArea function using binary scope- resolution operator (::).
286.
40 // calculateCylinder volume 41 double Cylinder::getVolume() const 42 { 43 return Circle4::getArea() * getHeight(); 44 45 } // end function getVolume 46 47 // output Cylinder object 48 void Cylinder::print() const 49 { 50 Circle4::print(); 51 cout << "; Height = " << getHeight(); 52 53 } // end function print Redefine class Circle4’s member function print.Invoke base-class Circle4’s print function using binary scope-resolution operator (::). Invoke base-class Circle4’s getArea function using binary scope- resolution operator (::).
287.
1 // Example55 2 // Testing class Cylinder. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 using std::fixed; 8 9 #include <iomanip> 10 11 using std::setprecision; 12 13 #include "cylinder.h" // Cylinder class definition 14 15 int main() 16 { 17 // instantiate Cylinder object 18 Cylinder cylinder( 12, 23, 2.5, 5.7 ); 19 20 // display point coordinates 21 cout << "X coordinate is " << cylinder.getX() 22 << "nY coordinate is " << cylinder.getY() 23 << "nRadius is " << cylinder.getRadius() 24 << "nHeight is " << cylinder.getHeight(); 25 Invoke indirectly inherited Point3 member functions. Invoke directly inherited Circle4 member function. Invoke Cylinder member function.
288.
26 cylinder.setX( 2); // set new x-coordinate 27 cylinder.setY( 2 ); // set new y-coordinate 28 cylinder.setRadius( 4.25 ); // set new radius 29 cylinder.setHeight( 10 ); // set new height 30 31 // display new cylinder value 32 cout << "nnThe new location and radius of circle aren"; 33 cylinder.print(); 34 35 // display floating-point values with 2 digits of precision 36 cout << fixed << setprecision( 2 ); 37 38 // display cylinder's diameter 39 cout << "nnDiameter is " << cylinder.getDiameter(); 40 41 // display cylinder's circumference 42 cout << "nCircumference is " 43 << cylinder.getCircumference(); 44 45 // display cylinder's area 46 cout << "nArea is " << cylinder.getArea(); 47 48 // display cylinder's volume 49 cout << "nVolume is " << cylinder.getVolume(); 50 Invoke indirectly inherited Point3 member functions. Invoke directly inherited Circle4 member function.Invoke Cylinder member function. Invoke redefined print function. Invoke redefined getArea function.
289.
51 cout <<endl; 52 53 return 0; // indicates successful termination 54 55 } // end main X coordinate is 12 Y coordinate is 23 Radius is 2.5 Height is 5.7 The new location and radius of circle are Center = [2, 2]; Radius = 4.25; Height = 10 Diameter is 8.50 Circumference is 26.70 Area is 380.53 Volume is 567.45
290.
Software Engineering withInheritance Customizing existing software Inherit from existing classes Include additional members Redefine base-class members No direct access to base class’s source code Link to object code Independent software vendors (ISVs) Develop proprietary code for sale/license Available in object-code format Users derive new classes Without accessing ISV proprietary source code
291.
Introduction Polymorphism “Programin the general” Derived-class object can be treated as base-class object “is-a” relationship Base class is not a derived class object Virtual functions and dynamic binding Makes programs extensible New classes added easily, can still be processed Examples Use abstract base class Shape Defines common interface (functionality) Point, Circle and Cylinder inherit from Shape Polymorphism
292.
Invoking Base-Class Functionsfrom Derived- Class Objects Pointers to base/derived objects Base pointer aimed at derived object “is a” relationship Circle “is a” Point Will invoke base class functions Can cast base-object’s address to derived-class pointer Called down-casting Allows derived-class functionality Key point Base-pointer can aim at derived-object - but can only call base-class functions Data type of pointer/reference determines functions it can call
293.
1 // Example56 2 // Aiming base-class and derived-class pointers at base-class 3 // and derived-class objects, respectively. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 using std::fixed; 9 10 #include <iomanip> 11 12 using std::setprecision; 13 14 #include "point.h" // Point class definition 15 #include "circle.h" // Circle class definition 16 17 int main() 18 { 19 Point point( 30, 50 ); 20 Point *pointPtr = 0; // base-class pointer 21 22 Circle circle( 120, 89, 2.7 ); 23 Circle *circlePtr = 0; // derived-class pointer 24
294.
25 // setfloating-point numeric formatting 26 cout << fixed << setprecision( 2 ); 27 28 // output objects point and circle 29 cout << "Print point and circle objects:" 30 << "nPoint: "; 31 point.print(); // invokes Point's print 32 cout << "nCircle: "; 33 circle.print(); // invokes Circle's print 34 35 // aim base-class pointer at base-class object and print 36 pointPtr = &point; 37 cout << "nnCalling print with base-class pointer to " 38 << "nbase-class object invokes base-class print " 39 << "function:n"; 40 pointPtr->print(); // invokes Point's print 41 42 // aim derived-class pointer at derived-class object 43 // and print 44 circlePtr = &circle; 45 cout << "nnCalling print with derived-class pointer to " 46 << "nderived-class object invokes derived-class " 47 << "print function:n"; 48 circlePtr->print(); // invokes Circle's print 49 Use objects and pointers to call the print function. The pointers and objects are of the same class, so the proper print function is called.
295.
50 // aimbase-class pointer at derived-class object and print 51 pointPtr = &circle; 52 cout << "nnCalling print with base-class pointer to " 53 << "derived-class objectninvokes base-class print " 54 << "function on that derived-class object:n"; 55 pointPtr->print(); // invokes Point's print 56 cout << endl; 57 58 return 0; 59 60 } // end main Aiming a base-class pointer at a derived object is allowed (the Circle “is a” Point). However, it calls Point’s print function, determined by the pointer type. virtual functions allow us to change this.
296.
1 // Example57 2 // Aiming a derived-class pointer at a base-class object. 3 #include "point.h" // Point class definition 4 #include "circle.h" // Circle class definition 5 6 int main() 7 { 8 Point point( 30, 50 ); 9 Circle *circlePtr = 0; 10 11 // aim derived-class pointer at base-class object 12 circlePtr = &point; // Error: a Point is not a Circle 13 14 return 0; 15 16 } // end main C:cpphtp4examplesch10fig10_06Fig10_06.cpp(12) : error C2440: '=' : cannot convert from 'class Point *' to 'class Circle *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
297.
1 // Example58 2 // Attempting to invoke derived-class-only member functions 3 // through a base-class pointer. 4 #include "point.h" // Point class definition 5 #include "circle.h" // Circle class definition 6 7 int main() 8 { 9 Point *pointPtr = 0; 10 Circle circle( 120, 89, 2.7 ); 11 12 // aim base-class pointer at derived-class object 13 pointPtr = &circle; 14 15 // invoke base-class member functions on derived-class 16 // object through base-class pointer 17 int x = pointPtr->getX(); 18 int y = pointPtr->getY(); 19 pointPtr->setX( 10 ); 20 pointPtr->setY( 10 ); 21 pointPtr->print(); 22
298.
23 // attemptto invoke derived-class-only member functions 24 // on derived-class object through base-class pointer 25 double radius = pointPtr->getRadius(); 26 pointPtr->setRadius( 33.33 ); 27 double diameter = pointPtr->getDiameter(); 28 double circumference = pointPtr->getCircumference(); 29 double area = pointPtr->getArea(); 30 31 return 0; 32 33 } // end main These functions are only defined in Circle. However, pointPtr is of class Point.
299.
Virtual Functions virtualfunctions Object (not pointer) determines function called Why useful? Suppose Circle, Triangle, Rectangle derived from Shape Each has own draw function To draw any shape Have base class Shape pointer, call draw Program determines proper draw function at run time (dynamically) Treat all shapes generically
300.
Virtual Functions Declaredraw as virtual in base class Override draw in each derived class Like redefining, but new function must have same signature If function declared virtual, can only be overridden virtual void draw() const; Once declared virtual, virtual in all derived classes Good practice to explicitly declare virtual Dynamic binding Choose proper function to call at run time Only occurs off pointer handles If function called from object, uses that object’s definition
301.
Virtual Functions Polymorphism Same message, “print”, given to many objects All through a base pointer Message takes on “many forms” Summary Base-pointer to base-object, derived-pointer to derived Straightforward Base-pointer to derived object Can only call base-class functions Derived-pointer to base-object Compiler error Allowed if explicit cast made
302.
Polymorphism Examples Supposedesigning video game Base class SpaceObject Derived Martian, SpaceShip, LaserBeam Base function draw To refresh screen Screen manager has vector of base-class pointers to objects Send draw message to each object Same message has “many forms” of results Easy to add class Mercurian Inherits from SpaceObject Provides own definition for draw Screen manager does not need to change code Calls draw regardless of object’s type Mercurian objects “plug right in”
303.
Type Fields andswitch Structures One way to determine object's class Give base class an attribute shapeType in class Shape Use switch to call proper print function Many problems May forget to test for case in switch If add/remove a class, must update switch structures Time consuming and error prone Better to use polymorphism Less branching logic, simpler programs, less debugging
304.
Abstract Classes Abstractclasses Sole purpose: to be a base class (called abstract base classes) Incomplete Derived classes fill in "missing pieces" Cannot make objects from abstract class However, can have pointers and references Concrete classes Can instantiate objects Implement all functions they define Provide specifics
305.
Abstract Classes Abstractclasses not required, but helpful To make a class abstract Need one or more "pure" virtual functions Declare function with initializer of 0 virtual void draw() const = 0; Regular virtual functions Have implementations, overriding is optional Pure virtual functions No implementation, must be overridden Abstract classes can have data and concrete functions Required to have one or more pure virtual functions
306.
Case Study: InheritingInterface and Implementation Make abstract base class Shape Pure virtual functions (must be implemented) getName, print Default implementation does not make sense Virtual functions (may be redefined) getArea, getVolume Initially return 0.0 If not redefined, uses base class definition Derive classes Point, Circle, Cylinder
307.
Case Study: InheritingInterface and Implementation 0.0 0.0 = 0 = 0 0.0 0.0 "Point" [x,y] pr2 0.0 "Circle" center=[x,y]; radius=r 2pr2 +2prh pr2h "Cylinder" center=[x,y]; radius=r; height=h getArea printgetNamegetVolume Shape Point Circle Cylinder
308.
1 // Example59 2 // Shape abstract-base-class definition. 3 #ifndef SHAPE_H 4 #define SHAPE_H 5 6 #include <string> // C++ standard string class 7 8 using std::string; 9 10 class Shape { 11 12 public: 13 14 // virtual function that returns shape area 15 virtual double getArea() const; 16 17 // virtual function that returns shape volume 18 virtual double getVolume() const; 19 20 // pure virtual functions; overridden in derived classes 21 virtual string getName() const = 0; // return shape name 22 virtual void print() const = 0; // output shape 23 24 }; // end class Shape 25 26 #endif Virtual and pure virtual functions.
309.
1 // Example60 2 // Shape class member-function definitions. 3 #include <iostream> 4 5 using std::cout; 6 7 #include "shape.h" // Shape class definition 8 9 // return area of shape; 0.0 by default 10 double getArea() const 11 { 12 return 0.0; 13 14 } // end function getArea 15 16 // return volume of shape; 0.0 by default 17 double getVolume() const 18 { 19 return 0.0; 20 21 } // end function getVolume
310.
Polymorphism, Virtual Functionsand Dynamic Binding “Under the Hood” Polymorphism has overhead Not used in STL (Standard Template Library) to optimize performance virtual function table (vtable) Every class with a virtual function has a vtable For every virtual function, vtable has pointer to the proper function If derived class has same function as base class Function pointer aims at base-class function
311.
Virtual Destructors Baseclass pointer to derived object If destroyed using delete, behavior unspecified Simple fix Declare base-class destructor virtual Makes derived-class destructors virtual Now, when delete used appropriate destructor called When derived-class object destroyed Derived-class destructor executes first Base-class destructor executes afterwards Constructors cannot be virtual
312.
Case Study: PayrollSystem Using Polymorphism Create a payroll program Use virtual functions and polymorphism Problem statement 4 types of employees, paid weekly Salaried (fixed salary, no matter the hours) Hourly (overtime [>40 hours] pays time and a half) Commission (paid percentage of sales) Base-plus-commission (base salary + percentage of sales) Boss wants to raise pay by 10%
313.
Payroll System Using Polymorphism Base class Employee Pure virtual function earnings (returns pay) Pure virtual because need to know employee type Cannot calculate for generic employee Other classes derive from Employee Employee SalariedEmployee HourlyEmployeeCommissionEmployee BasePlusCommissionEmployee
314.
Dynamic Cast Downcasting dynamic_cast operator Determine object's type at runtime Returns 0 if not of proper type (cannot be cast) NewClass *ptr = dynamic_cast < NewClass *> objectPtr; Keyword typeid Header <typeinfo> Usage: typeid(object) Returns type_info object Has information about type of operand, including name typeid(object).name()
43 // genericallyprocess each element in vector employees 44 for ( int i = 0; i < employees.size(); i++ ) { 45 46 // output employee information 47 employees[ i ]->print(); 48 49 // downcast pointer 50 BasePlusCommissionEmployee *commissionPtr = 51 dynamic_cast < BasePlusCommissionEmployee * > 52 ( employees[ i ] ); 53 54 // determine whether element points to base-salaried 55 // commission employee 56 if ( commissionPtr != 0 ) { 57 cout << "old base salary: $" 58 << commissionPtr->getBaseSalary() << endl; 59 commissionPtr->setBaseSalary( 60 1.10 * commissionPtr->getBaseSalary() ); 61 cout << "new base salary with 10% increase is: $" 62 << commissionPtr->getBaseSalary() << endl; 63 64 } // end if 65 66 cout << "earned $" << employees[ i ]->earnings() << endl; 67 68 } // end for 69 Use downcasting to cast the employee object into a BasePlusCommissionEmployee. If it points to the correct type of object, the pointer is non-zero. This way, we can give a raise to only BasePlusCommissionEmployees.
337.
70 // releasememory held by vector employees 71 for ( int j = 0; j < employees.size(); j++ ) { 72 73 // output class name 74 cout << "ndeleting object of " 75 << typeid( *employees[ j ] ).name(); 76 77 delete employees[ j ]; 78 79 } // end for 80 81 cout << endl; 82 83 return 0; 84 85 } // end main typeid returns a type_info object. This object contains information about the operand, including its name.
338.
salaried employee: JohnSmith social security number: 111-11-1111 earned $800.00 commission employee: Sue Jones social security number: 222-22-2222 earned $600.00 base-salaried commission employee: Bob Lewis social security number: 333-33-3333 old base salary: $300.00 new base salary with 10% increase is: $330.00 earned $530.00 hourly employee: Karen Price social security number: 444-44-4444 earned $670.00 deleting object of class SalariedEmployee deleting object of class CommissionEmployee deleting object of class BasePlusCommissionEmployee deleting object of class HourlyEmployee
339.
Multiple Inheritance Multipleinheritance Derived class has several base classes Powerful, but can cause ambiguity problems If both base classes have functions of the same name Solution: specify exact function using :: myObject.BaseClass1::function() Format Use comma-separated list class Derived : public Base1, public Base2{ contents }
340.
1 // Example72 2 // Definition of class Base1 3 #ifndef BASE1_H 4 #define BASE1_H 5 6 // class Base1 definition 7 class Base1 { 8 public: 9 Base1( int parameterValue ) { value = parameterValue; } 10 int getData() const { return value; } 11 12 protected: // accessible to derived classes 13 int value; // inherited by derived class 14 15 }; // end class Base1 16 17 #endif // BASE1_H There are two base classes in this example, each has its own getData function. This base class contains an int.
341.
1 // Example73 2 // Definition of class Base2 3 #ifndef BASE2_H 4 #define BASE2_H 5 6 // class Base2 definition 7 class Base2 { 8 public: 9 Base2( char characterData ) { letter = characterData; } 10 char getData() const { return letter; } 11 12 protected: // accessible to derived classes 13 char letter; // inherited by derived class 14 15 }; // end class Base2 16 17 #endif // BASE2_H
342.
1 // Example74 2 // Definition of class Derived which inherits 3 // multiple base classes (Base1 and Base2). 4 #ifndef DERIVED_H 5 #define DERIVED_H 6 7 #include <iostream> 8 9 using std::ostream; 10 11 #include "base1.h" 12 #include "base2.h" 13 14 // class Derived definition 15 class Derived : public Base1, public Base2 { 16 friend ostream &operator<<( ostream &, const Derived & ); 17 18 public: 19 Derived( int, char, double ); 20 double getReal() const; 21 22 private: 23 double real; // derived class's private data 24 25 }; // end class Derived 26 27 #endif // DERIVED_H Use comma-separated list.
343.
1 // Example75 2 // Member function definitions for class Derived 3 #include "derived.h" 4 5 // constructor for Derived calls constructors for 6 // class Base1 and class Base2. 7 // use member initializers to call base-class constructors 8 Derived::Derived( int integer, char character, double double1 ) 9 : Base1( integer ), Base2( character ), real( double1 ) { } 10 11 // return real 12 double Derived::getReal() const { return real; } 13 14 // display all data members of Derived 15 ostream &operator<<( ostream &output, const Derived &derived ) 16 { 17 output << " Integer: " << derived.value 18 << "n Character: " << derived.letter 19 << "nReal number: " << derived.real; 20 21 return output; // enables cascaded calls 22 23 } // end operator<< Note use of base-class constructors in derived class constructor.
25 // printdata members of derived-class object 26 // scope resolution operator resolves getData ambiguity 27 cout << "Data members of Derived can be" 28 << " accessed individually:" 29 << "n Integer: " << derived.Base1::getData() 30 << "n Character: " << derived.Base2::getData() 31 << "nReal number: " << derived.getReal() << "nn"; 32 33 cout << "Derived can be treated as an " 34 << "object of either base class:n"; 35 36 // treat Derived as a Base1 object 37 base1Ptr = &derived; 38 cout << "base1Ptr->getData() yields " 39 << base1Ptr->getData() << 'n'; 40 41 // treat Derived as a Base2 object 42 base2Ptr = &derived; 43 cout << "base2Ptr->getData() yields " 44 << base2Ptr->getData() << endl; 45 46 return 0; 47 48 } // end main Note calls to specific base class functions. Can treat derived-class pointer as either base-class pointer.
346.
Object base1 containsinteger 10 Object base2 contains character Z Object derived contains: Integer: 7 Character: A Real number: 3.5 Data members of Derived can be accessed individually: Integer: 7 Character: A Real number: 3.5 Derived can be treated as an object of either base class: base1Ptr->getData() yields 7 base2Ptr->getData() yields A
347.
Multiple Inheritance andvirtual Base Classes Ambiguities from multiple inheritance iostream could have duplicate subobjects Data from ios inherited into ostream and istream Upcasting iostream pointer to ios object is a problem Two ios subobjects could exist, which is used? Ambiguous, results in syntax error iostream does not actually have this problem ios ostream istream iostream
348.
Multiple Inheritance andvirtual Base Classes Solution: use virtual base class inheritance Only one subobject inherited into multiply derived class Second Derived Class Base Class First Derived Class Multiply-Derived Class virtual inheritance virtual inheritance
349.
1 // Example77 2 // Attempting to polymorphically call a function that is 3 // multiply inherited from two base classes. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 // class Base definition 10 class Base { 11 public: 12 virtual void print() const = 0; // pure virtual 13 14 }; // end class Base 15 16 // class DerivedOne definition 17 class DerivedOne : public Base { 18 public: 19 20 // override print function 21 void print() const { cout << "DerivedOnen"; } 22 23 }; // end class DerivedOne 24 This example will demonstrate the ambiguity of multiple inheritance.
350.
25 // classDerivedTwo definition 26 class DerivedTwo : public Base { 27 public: 28 29 // override print function 30 void print() const { cout << "DerivedTwon"; } 31 32 }; // end class DerivedTwo 33 34 // class Multiple definition 35 class Multiple : public DerivedOne, public DerivedTwo { 36 public: 37 38 // qualify which version of function print 39 void print() const { DerivedTwo::print(); } 40 41 }; // end class Multiple 42
351.
43 int main() 44{ 45 Multiple both; // instantiate Multiple object 46 DerivedOne one; // instantiate DerivedOne object 47 DerivedTwo two; // instantiate DerivedTwo object 48 49 // create array of base-class pointers 50 Base *array[ 3 ]; 51 52 array[ 0 ] = &both; // ERROR--ambiguous 53 array[ 1 ] = &one; 54 array[ 2 ] = &two; 55 56 // polymorphically invoke print 57 for ( int i = 0; i < 3; i++ ) 58 array[ i ] -> print(); 59 60 return 0; 61 62 } // end main Which base subobject will be used?
352.
1 // Example78 2 // Using virtual base classes. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 // class Base definition 9 class Base { 10 public: 11 12 // implicit default constructor 13 14 virtual void print() const = 0; // pure virtual 15 16 }; // end Base class 17 18 // class DerivedOne definition 19 class DerivedOne : virtual public Base { 20 public: 21 22 // implicit default constructor calls 23 // Base default constructor 24 25 // override print function 26 void print() const { cout << "DerivedOnen"; } 27 28 }; // end DerivedOne class Use virtual inheritance to solve the ambiguity problem. The compiler generates default constructors, which greatly simplifies the hierarchy.
353.
29 30 // classDerivedTwo definition 31 class DerivedTwo : virtual public Base { 32 public: 33 34 // implicit default constructor calls 35 // Base default constructor 36 37 // override print function 38 void print() const { cout << "DerivedTwon"; } 39 40 }; // end DerivedTwo class 41 42 // class Multiple definition 43 class Multiple : public DerivedOne, public DerivedTwo { 44 public: 45 46 // implicit default constructor calls 47 // DerivedOne and DerivedTwo default constructors 48 49 // qualify which version of function print 50 void print() const { DerivedTwo::print(); } 51 52 }; // end Multiple class Use virtual inheritance, as before.
354.
53 54 int main() 55{ 56 Multiple both; // instantiate Multiple object 57 DerivedOne one; // instantiate DerivedOne object 58 DerivedTwo two; // instantiate DerivedTwo object 59 60 // declare array of base-class pointers and initialize 61 // each element to a derived-class type 62 Base *array[ 3 ]; 63 64 array[ 0 ] = &both; 65 array[ 1 ] = &one; 66 array[ 2 ] = &two; 67 68 // polymorphically invoke function print 69 for ( int i = 0; i < 3; i++ ) 70 array[ i ]->print(); 71 72 return 0; 73 74 } // end main DerivedTwo DerivedOne DerivedTwo
355.
Program Design andSoftware Tools Template, Standard Template Library Template
356.
Introduction Overloaded functions Similar operations but Different types of data Function templates Specify entire range of related (overloaded) functions Function-template specializations Identical operations Different types of data Single function template Compiler generates separate object-code functions Unlike Macros they allow Type checking Class templates Specify entire range of related classes Class-template specializations
357.
Function Templates Function-templatedefinitions Keyword template List formal type parameters in angle brackets (< and >) Each parameter preceded by keyword class or typename class and typename interchangeable template< class T > template< typename ElementType > template< class BorderType, class FillType > Specify types of Arguments to function Return type of function Variables within function
358.
1 // Example79 2 // Using template functions. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 // function template printArray definition 9 template< class T > 10 void printArray( const T *array, const int count ) 11 { 12 for ( int i = 0; i < count; i++ ) 13 cout << array[ i ] << " "; 14 15 cout << endl; 16 17 } // end function printArray 18 19 int main() 20 { 21 const int aCount = 5; 22 const int bCount = 7; 23 const int cCount = 6; 24 Function template definition; declare single formal type parameter T. T is type parameter; use any valid identifier. If T is user-defined type, stream-insertion operator must be overloaded for class T.
359.
25 int a[aCount ] = { 1, 2, 3, 4, 5 }; 26 double b[ bCount ] = { 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7 }; 27 char c[ cCount ] = "HELLO"; // 6th position for null 28 29 cout << "Array a contains:" << endl; 30 31 // call integer function-template specialization 32 printArray( a, aCount ); 33 34 cout << "Array b contains:" << endl; 35 36 // call double function-template specialization 37 printArray( b, bCount ); 38 39 cout << "Array c contains:" << endl; 40 41 // call character function-template specialization 42 printArray( c, cCount ); 43 44 return 0; 45 46 } // end main Creates complete function-template specialization for printing array of ints: void printArray( const int *array, const int count ) { for ( int i = 0; i < count; i++ ) cout << array[ i ] << " " cout << endl; } // end function printArray Compiler infers T is double; instantiates function-template specialization where T is double. Compiler infers T is char; instantiates function-template specialization where T is char.
360.
Overloading Function Templates Related function-template specializations Same name Compiler uses overloading resolution Function template overloading Other function templates with same name Different parameters Non-template functions with same name Different function arguments Compiler performs matching process Tries to find precise match of function name and argument types If fails, function template Generate function-template specialization with precise match
361.
Class Templates Stack LIFO (last-in-first-out) structure Class templates Generic programming Describe notion of stack generically Instantiate type-specific version Parameterized types Require one or more type parameters Customize “generic class” template to form class-template specialization
362.
1 // Example80 2 // Stack class template. 3 #ifndef TSTACK1_H 4 #define TSTACK1_H 5 6 template< class T > 7 class Stack { 8 9 public: 10 Stack( int = 10 ); // default constructor (stack size 10) 11 12 // destructor 13 ~Stack() 14 { 15 delete [] stackPtr; 16 17 } // end ~Stack destructor 18 19 bool push( const T& ); // push an element onto the stack 20 bool pop( T& ); // pop an element off the stack 21 Specify class-template definition; type parameter T indicates type of Stack class to be created. Function parameters of type T.
363.
22 // determinewhether Stack is empty 23 bool isEmpty() const 24 { 25 return top == -1; 26 27 } // end function isEmpty 28 29 // determine whether Stack is full 30 bool isFull() const 31 { 32 return top == size - 1; 33 34 } // end function isFull 35 36 private: 37 int size; // # of elements in the stack 38 int top; // location of the top element 39 T *stackPtr; // pointer to the stack 40 41 }; // end class Stack 42 Array of elements of type T.
364.
43 // constructor 44template< class T > 45 Stack< T >::Stack( int s ) 46 { 47 size = s > 0 ? s : 10; 48 top = -1; // Stack initially empty 49 stackPtr = new T[ size ]; // allocate memory for elements 50 51 } // end Stack constructor 52 53 // push element onto stack; 54 // if successful, return true; otherwise, return false 55 template< class T > 56 bool Stack< T >::push( const T &pushValue ) 57 { 58 if ( !isFull() ) { 59 stackPtr[ ++top ] = pushValue; // place item on Stack 60 return true; // push successful 61 62 } // end if 63 64 return false; // push unsuccessful 65 66 } // end function push 67 Member functions preceded with header template< class T > Use binary scope resolution operator (::) with class- template name (Stack< T >) to tie definition to class template’s scope. Constructor creates array of type T. For example, compiler generates stackPtr = new T[ size ]; for class-template specialization Stack< double >.
365.
68 // popelement off stack; 69 // if successful, return true; otherwise, return false 70 template< class T > 71 bool Stack< T >::pop( T &popValue ) 72 { 73 if ( !isEmpty() ) { 74 popValue = stackPtr[ top-- ]; // remove item from Stack 75 return true; // pop successful 76 77 } // end if 78 79 return false; // pop unsuccessful 80 81 } // end function pop 82 83 #endif Member function preceded with header template< class T >Use binary scope resolution operator (::) with class- template name (Stack< T >) to tie definition to class template’s scope.
366.
1 // Example81 2 // Stack-class-template test program. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 #include "tstack1.h" // Stack class template definition 10 11 int main() 12 { 13 Stack< double > doubleStack( 5 ); 14 double doubleValue = 1.1; 15 16 cout << "Pushing elements onto doubleStackn"; 17 18 while ( doubleStack.push( doubleValue ) ) { 19 cout << doubleValue << ' '; 20 doubleValue += 1.1; 21 22 } // end while 23 24 cout << "nStack is full. Cannot push " << doubleValue 25 << "nnPopping elements from doubleStackn"; Link to class template definition. Instantiate object of class Stack< double >. Invoke function push of class-template specialization Stack< double >.
367.
26 27 while (doubleStack.pop( doubleValue ) ) 28 cout << doubleValue << ' '; 29 30 cout << "nStack is empty. Cannot popn"; 31 32 Stack< int > intStack; 33 int intValue = 1; 34 cout << "nPushing elements onto intStackn"; 35 36 while ( intStack.push( intValue ) ) { 37 cout << intValue << ' '; 38 ++intValue; 39 40 } // end while 41 42 cout << "nStack is full. Cannot push " << intValue 43 << "nnPopping elements from intStackn"; 44 45 while ( intStack.pop( intValue ) ) 46 cout << intValue << ' '; 47 48 cout << "nStack is empty. Cannot popn"; 49 50 return 0; Invoke function pop of class- template specialization Stack< double >. Note similarity of code for Stack< int > to code for Stack< double >.
368.
51 52 } //end main Pushing elements onto doubleStack 1.1 2.2 3.3 4.4 5.5 Stack is full. Cannot push 6.6 Popping elements from doubleStack 5.5 4.4 3.3 2.2 1.1 Stack is empty. Cannot pop Pushing elements onto intStack 1 2 3 4 5 6 7 8 9 10 Stack is full. Cannot push 11 Popping elements from intStack 10 9 8 7 6 5 4 3 2 1 Stack is empty. Cannot pop
369.
1 // Example82 2 // Stack class template test program. Function main uses a 3 // function template to manipulate objects of type Stack< T >. 4 #include <iostream> 5 6 using std::cout; 7 using std::cin; 8 using std::endl; 9 10 #include "tstack1.h" // Stack class template definition 11 12 // function template to manipulate Stack< T > 13 template< class T > 14 void testStack( 15 Stack< T > &theStack, // reference to Stack< T > 16 T value, // initial value to push 17 T increment, // increment for subsequent values 18 const char *stackName ) // name of the Stack < T > object 19 { 20 cout << "nPushing elements onto " << stackName << 'n'; 21 22 while ( theStack.push( value ) ) { 23 cout << value << ' '; 24 value += increment; 25 26 } // end while Function template to manipulat Stack< T > eliminates simil code from previous file for Stack< double > and Stack< int >.
370.
27 28 cout <<"nStack is full. Cannot push " << value 29 << "nnPopping elements from " << stackName << 'n'; 30 31 while ( theStack.pop( value ) ) 32 cout << value << ' '; 33 34 cout << "nStack is empty. Cannot popn"; 35 36 } // end function testStack 37 38 int main() 39 { 40 Stack< double > doubleStack( 5 ); 41 Stack< int > intStack; 42 43 testStack( doubleStack, 1.1, 1.1, "doubleStack" ); 44 testStack( intStack, 1, 1, "intStack" ); 45 46 return 0; 47 48 } // end main
371.
Pushing elements ontodoubleStack 1.1 2.2 3.3 4.4 5.5 Stack is full. Cannot push 6.6 Popping elements from doubleStack 5.5 4.4 3.3 2.2 1.1 Stack is empty. Cannot pop Pushing elements onto intStack 1 2 3 4 5 6 7 8 9 10 Stack is full. Cannot push 11 Popping elements from intStack 10 9 8 7 6 5 4 3 2 1 Stack is empty. Cannot pop Note output identical to that of fig11_03.cpp.
372.
Class templates Nontype parameters Default arguments Treated as consts template< class T, int elements > Stack< double, 100 > mostRecentSalesFigures; Declares object of type Stack< double, 100> Type parameter Default type example: template< class T = string > Overriding class templates Class for specific type Does not match common class template Example: template<> Class Array< Martian > { // body of class definition }; Class Templates and Nontype Parameters
373.
Templates and Inheritance Several ways of relating templates and inheritance Class template derived from class-template specialization Class template derived from non-template class Class-template specialization derived from class-template specialization Non-template class derived from class-template specialization Friendships between class template and Global function Member function of another class Entire class
374.
Templates and Friends friend functions Inside definition of template< class T > class X friend void f1(); f1() friend of all class-template specializations friend void f2( X< T > & ); f2( X< float > & ) friend of X< float > only, f2( X< double > & ) friend of X< double > only, f2( X< int > & ) friend of X< int > only, … friend void A::f4(); Member function f4 of class A friend of all class-template specializations
375.
Templates and Friends friend functions Inside definition of template< class T > class X friend void C< T >::f5( X< T > & ); Member function C<float>::f5( X< float> & ) friend of class X<float> only friend classes Inside definition of template< class T > class X friend class Y; Every member function of Y friend of every class-template specialization friend class Z<T>; class Z<float> friend of class-template specialization X<float>, etc.
376.
Templates and staticMembers Non-template class static data members shared between all objects Class-template specialization Each has own copy of static data members static variables initialized at file scope Each has own copy of static member functions
377.
Introduction to theStandard Template Library (STL) STL Powerful, template-based components Containers: template data structures Iterators: like pointers, access elements of containers Algorithms: data manipulation, searching, sorting, etc. Object- oriented programming: reuse, reuse, reuse Only an introduction to STL, a huge class library
378.
Introduction to Containers Three types of containers Sequence containers: vector; deque; list Linear data structures (vectors, linked lists) First-class container Associative containers: set; multiset; map; multimap Non-linear, can find elements quickly Key/value pairs First-class container Container adapters:stack; queue; priority_queue Near containers Similar to containers, with reduced functionality Containers have some common functions
379.
Common STL MemberFunctions Member functions for all containers Default constructor, copy constructor, destructor empty max_size, size = < <= > >= == != swap Functions for first-class containers begin, end rbegin, rend erase, clear
Introduction to Iterators Iterators similar to pointers Point to first element in a container Iterator operators same for all containers * dereferences ++ points to next element begin() returns iterator to first element end() returns iterator to last element Use iterators with sequences (ranges) Containers Input sequences: istream_iterator Output sequences: ostream_iterator
382.
Iterators Usage std::istream_iterator<int > inputInt( cin ) Can read input from cin *inputInt: Dereference to read first int from cin ++inputInt: Go to next int in stream std::ostream_iterator< int > outputInt(cout) Can output ints to cout *outputInt = 7: Outputs 7 to cout ++outputInt: Advances iterator so we can output next int Example int number1 = *inputInt; ++inputInt int number1 = *inputInt; cout << "The sum is: "; *outputInt = number1 + number2;
383.
Iterator Categories Input Read elements from container, can only move forward Output Write elements to container, only forward Forward Combines input and output, retains position Bidirectional Like forward, but can move backwards as well Multi-pass (can pass through sequence twice) Random access Like bidirectional, but can also jump to any element
Iterator Operations All ++p, p++ Input iterators *p (to use as rvalue) p = p1 p == p1, p != p1 Output iterators *p p = p1 Forward iterators Have functionality of input and output iterators Bidirectional --p, p-- Random access p + i, p += i p - i, p -= i p[i] p < p1, p <= p1 p > p1, p >= p1
386.
Introduction to Algorithms STL has algorithms used generically across containers Operate on elements indirectly via iterators Often operate on sequences of elements Defined by pairs of iterators First and last element Algorithms often return iterators find() Returns iterator to element, or end() if not found Premade algorithms save programmers time and effort
387.
vector Sequence Container vector Has random access iterators Data structure with contiguous memory locations Access elements with [] Use when data must be sorted and easily accessible When memory exhausted Allocates larger, contiguous area of memory Copies itself there Deallocates old memory Declarations std::vector <type> v; type: int, float, etc.
388.
vector Sequence Container Iterators std::vector<type>::const_iterator iterVar; const_iterator cannot modify elements (read) std::vector<type>::reverse_iterator iterVar; Visits elements in reverse order (end to beginning) Use rbegin to get starting point Use rend to get ending point vector functions v.push_back(value) Add element to end (found in all sequence containers). v.size() Current size of vector v.capacity() How much vector can hold before reallocating memory Reallocation doubles size vector<type> v(a, a + SIZE) Creates vector v with elements from array a up to (not including) a + SIZE
389.
vector Sequence Container vector functions v.insert(iterator, value ) Inserts value before location of iterator v.insert(iterator, array , array + SIZE) Inserts array elements (up to, but not including array + SIZE) into vector v.erase( iterator ) Remove element from container v.erase( iter1, iter2 ) Remove elements starting from iter1 and up to (not including) iter2 v.clear() Erases entire container vector functions operations v.front(), v.back() Return first and last element v.[elementNumber] = value; Assign value to an element v.at[elementNumber] = value; As above, with range checking out_of_bounds exception
390.
vector Sequence Container ostream_iterator std::ostream_iterator< type > Name( outputStream, separator ); type: outputs values of a certain type outputStream: iterator output location separator: character separating outputs Example std::ostream_iterator< int > output( cout, " " ); std::copy( iterator1, iterator2, output ); Copies elements from iterator1 up to (not including) iterator2 to output, an ostream_iterator
391.
list Sequence Container list container : Header <list> Efficient insertion/deletion anywhere in container Doubly-linked list (two pointers per node) Bidirectional iterators std::list< type > name; list functions for object t t.sort() Sorts in ascending order t.splice(iterator, otherObject ); Inserts values from otherObject before iterator t.merge( otherObject ) Removes otherObject and inserts it into t, sorted t.unique() Removes duplicate elements t.swap(otherObject); Exchange contents t.assign(iterator1, iterator2) Replaces contents with elements in range of iterators t.remove(value) Erases all instances of value
392.
deque Sequence Container deque ("deek"): double-ended queue Header <deque> Indexed access using [] Efficient insertion/deletion in front and back Non-contiguous memory: has "smarter" iterators Same basic operations as vector Also has push_front (insert at front of deque) pop_front (delete from front)
393.
Associative Containers Associativecontainers Direct access to store/retrieve elements Uses keys (search keys) 4 types: multiset, set, multimap and map Keys in sorted order multiset and multimap allow duplicate keys multimap and map have keys and associated values multiset and set only have values
394.
multiset Associative Container multiset Header <set> Fast storage, retrieval of keys (no values) Allows duplicates Bidirectional iterators Ordering of elements Done by comparator function object Used when creating multiset For integer multiset less<int> comparator function object multiset< int, std::less<int> > myObject; Elements will be sorted in ascending order
395.
Multiset Associative Container Multiset functions ms.insert(value) Inserts value into multiset ms.count(value) Returns number of occurrences of value ms.find(value) Returns iterator to first instance of value ms.lower_bound(value) Returns iterator to first location of value ms.upper_bound(value) Returns iterator to location after last occurrence of value Class pair Manipulate pairs of values Pair objects contain first and second const_iterators For a pair object q q = ms.equal_range(value) Sets first and second to lower_bound and upper_bound for a given value
396.
1 // Example83 2 // Testing Standard Library class multiset 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <set> // multiset class-template definition 9 10 // define short name for multiset type used in this program 11 typedef std::multiset< int, std::less< int > > ims; 12 13 #include <algorithm> // copy algorithm 14 15 int main() 16 { 17 const int SIZE = 10; 18 int a[ SIZE ] = { 7, 22, 9, 1, 18, 30, 100, 22, 85, 13 }; 19 20 ims intMultiset; // ims is typedef for "integer multiset" 21 std::ostream_iterator< int > output( cout, " " ); 22 23 cout << "There are currently " << intMultiset.count( 15 ) 24 << " values of 15 in the multisetn"; 25 typedefs help clarify program. This declares an integer multiset that stores values in ascending order.
397.
26 intMultiset.insert( 15); // insert 15 in intMultiset 27 intMultiset.insert( 15 ); // insert 15 in intMultiset 28 29 cout << "After inserts, there are " 30 << intMultiset.count( 15 ) 31 << " values of 15 in the multisetnn"; 32 33 // iterator that cannot be used to change element values 34 ims::const_iterator result; 35 36 // find 15 in intMultiset; find returns iterator 37 result = intMultiset.find( 15 ); 38 39 if ( result != intMultiset.end() ) // if iterator not at end 40 cout << "Found value 15n"; // found search value 15 41 42 // find 20 in intMultiset; find returns iterator 43 result = intMultiset.find( 20 ); 44 45 if ( result == intMultiset.end() ) // will be true hence 46 cout << "Did not find value 20n"; // did not find 20 47 48 // insert elements of array a into intMultiset 49 intMultiset.insert( a, a + SIZE ); 50 51 cout << "nAfter insert, intMultiset contains:n"; 52 std::copy( intMultiset.begin(), intMultiset.end(), output ); 53 Use member function find.
398.
54 // determinelower and upper bound of 22 in intMultiset 55 cout << "nnLower bound of 22: " 56 << *( intMultiset.lower_bound( 22 ) ); 57 cout << "nUpper bound of 22: " 58 << *( intMultiset.upper_bound( 22 ) ); 59 60 // p represents pair of const_iterators 61 std::pair< ims::const_iterator, ims::const_iterator > p; 62 63 // use equal_range to determine lower and upper bound 64 // of 22 in intMultiset 65 p = intMultiset.equal_range( 22 ); 66 67 cout << "nnequal_range of 22:" 68 << "n Lower bound: " << *( p.first ) 69 << "n Upper bound: " << *( p.second ); 70 71 cout << endl; 72 73 return 0; 74 75 } // end main Use a pair object to get the lower and upper bound for 22.
399.
There are currently0 values of 15 in the multiset After inserts, there are 2 values of 15 in the multiset Found value 15 Did not find value 20 After insert, intMultiset contains: 1 7 9 13 15 15 18 22 22 30 85 100 Lower bound of 22: 22 Upper bound of 22: 30 equal_range of 22: Lower bound: 22 Upper bound: 30
400.
Set Associative Container Set: Header <set> Implementation identical to multiset Unique keys: Duplicates ignored and not inserted Supports bidirectional iterators (but not random access) std::set< type, std::less<type> > name; Multimap: Header <map> Fast storage and retrieval of keys and associated values Has key/value pairs Duplicate keys allowed (multiple values for a single key) One-to-many relationship I.e., one student can take many courses Insert pair objects (with a key and value) Bidirectional iterators
401.
Multimap Associative Container Example std::multimap< int, double, std::less< int > > mmapObject; Key type int Value type double Sorted in ascending order Use typedef to simplify code typedef std::multimap<int, double, std::less<int>> mmid; mmid mmapObject; mmapObject.insert( mmid::value_type( 1, 3.4 ) ); Inserts key 1 with value 3.4 mmid::value_type creates a pair object
402.
1 // Example84 2 // Standard library class multimap test program. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <map> // map class-template definition 9 10 // define short name for multimap type used in this program 11 typedef std::multimap< int, double, std::less< int > > mmid; 12 13 int main() 14 { 15 mmid pairs; 16 17 cout << "There are currently " << pairs.count( 15 ) 18 << " pairs with key 15 in the multimapn"; 19 20 // insert two value_type objects in pairs 21 pairs.insert( mmid::value_type( 15, 2.7 ) ); 22 pairs.insert( mmid::value_type( 15, 99.3 ) ); 23 24 cout << "After inserts, there are " 25 << pairs.count( 15 ) 26 << " pairs with key 15nn"; Definition for a multimap that maps integer keys to double values. Create multimap and insert key-value pairs.
403.
27 28 // insertfive value_type objects in pairs 29 pairs.insert( mmid::value_type( 30, 111.11 ) ); 30 pairs.insert( mmid::value_type( 10, 22.22 ) ); 31 pairs.insert( mmid::value_type( 25, 33.333 ) ); 32 pairs.insert( mmid::value_type( 20, 9.345 ) ); 33 pairs.insert( mmid::value_type( 5, 77.54 ) ); 34 35 cout << "Multimap pairs contains:nKeytValuen"; 36 37 // use const_iterator to walk through elements of pairs 38 for ( mmid::const_iterator iter = pairs.begin(); 39 iter != pairs.end(); ++iter ) 40 cout << iter->first << 't' 41 << iter->second << 'n'; 42 43 cout << endl; 44 45 return 0; 46 47 } // end main Use iterator to print entire multimap.
404.
There are currently0 pairs with key 15 in the multimap After inserts, there are 2 pairs with key 15 Multimap pairs contains: Key Value 5 77.54 10 22.22 15 2.7 15 99.3 20 9.345 25 33.333 30 111.11
405.
Map Associative Container map Header <map> Like multimap, but only unique key/value pairs One-to-one mapping (duplicates ignored) Use [] to access values Example: for map object m m[30] = 4000.21; Sets the value of key 30 to 4000.21 If subscript not in map, creates new key/value pair Type declaration std::map< int, double, std::less< int > >;
406.
1 // Example85 2 // Standard library class map test program. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <map> // map class-template definition 9 10 // define short name for map type used in this program 11 typedef std::map< int, double, std::less< int > > mid; 12 13 int main() 14 { 15 mid pairs; 16 17 // insert eight value_type objects in pairs 18 pairs.insert( mid::value_type( 15, 2.7 ) ); 19 pairs.insert( mid::value_type( 30, 111.11 ) ); 20 pairs.insert( mid::value_type( 5, 1010.1 ) ); 21 pairs.insert( mid::value_type( 10, 22.22 ) ); 22 pairs.insert( mid::value_type( 25, 33.333 ) ); 23 pairs.insert( mid::value_type( 5, 77.54 ) ); // dupe ignored 24 pairs.insert( mid::value_type( 20, 9.345 ) ); 25 pairs.insert( mid::value_type( 15, 99.3 ) ); // dupe ignored 26 Again, use typedefs to simplify declaration. Duplicate keys ignored.
407.
27 cout <<"pairs contains:nKeytValuen"; 28 29 // use const_iterator to walk through elements of pairs 30 for ( mid::const_iterator iter = pairs.begin(); 31 iter != pairs.end(); ++iter ) 32 cout << iter->first << 't' 33 << iter->second << 'n'; 34 35 // use subscript operator to change value for key 25 36 pairs[ 25 ] = 9999.99; 37 38 // use subscript operator insert value for key 40 39 pairs[ 40 ] = 8765.43; 40 41 cout << "nAfter subscript operations, pairs contains:" 42 << "nKeytValuen"; 43 44 for ( mid::const_iterator iter2 = pairs.begin(); 45 iter2 != pairs.end(); ++iter2 ) 46 cout << iter2->first << 't' 47 << iter2->second << 'n'; 48 49 cout << endl; 50 51 return 0; 52 53 } // end main Can use subscript operator to add or change key-value pairs.
Container Adapters Containeradapters stack, queue and priority_queue Not first class containers Do not support iterators Do not provide actual data structure Programmer can select implementation Member functions push and pop stack Header <stack> Insertions and deletions at one end Last-in, first-out (LIFO) data structure Can use vector, list, or deque (default) Declarations stack<type, vector<type> > myStack; stack<type, list<type> > myOtherStack; stack<type> anotherStack; // default deque vector, list Implementation of stack (default deque) Does not change behavior, just performance (deque and vector fastest)
410.
Algorithms Before STL Class libraries incompatible among vendors Algorithms built into container classes STL separates containers and algorithms Easier to add new algorithms More efficient, avoids virtual function calls <algorithm>
411.
Basic Searching andSorting Algorithms find(iter1, iter2, value) Returns iterator to first instance of value (in range) find_if(iter1, iter2, function) Like find Returns iterator when function returns true sort(iter1, iter2) Sorts elements in ascending order binary_search(iter1, iter2, value) Searches ascending sorted list for value Uses binary search
412.
Function Objects Functionobjects (<functional>) Contain functions invoked using operator() STL function objects Type divides< T > arithmetic equal_to< T > relational greater< T > relational greater_equal< T > relational less< T > relational less_equal< T > relational logical_and< T > logical logical_not< T > logical logical_or< T > logical minus< T > arithmetic modulus< T > arithmetic negate< T > arithmetic not_equal_to< T > relational plus< T > arithmetic multiplies< T > arithmetic
413.
1 // Example86 2 // Demonstrating function objects. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <vector> // vector class-template definition 9 #include <algorithm> // copy algorithm 10 #include <numeric> // accumulate algorithm 11 #include <functional> // binary_function definition 12 13 // binary function adds square of its second argument and 14 // running total in its first argument, then returns sum 15 int sumSquares( int total, int value ) 16 { 17 return total + value * value; 18 19 } // end function sumSquares 20 Create a function to be used with accumulate.
414.
21 // binaryfunction class template defines overloaded operator() 22 // that adds suare of its second argument and running total in 23 // its first argument, then returns sum 24 template< class T > 25 class SumSquaresClass : public std::binary_function< T, T, T > { 26 27 public: 28 29 // add square of value to total and return result 30 const T operator()( const T &total, const T &value ) 31 { 32 return total + value * value; 33 34 } // end function operator() 35 36 }; // end class SumSquaresClass 37 Create a function object (it can also encapsulate data). Overload operator().
415.
38 int main() 39{ 40 const int SIZE = 10; 41 int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 42 43 std::vector< int > integers( array, array + SIZE ); 44 45 std::ostream_iterator< int > output( cout, " " ); 46 47 int result = 0; 48 49 cout << "vector v contains:n"; 50 std::copy( integers.begin(), integers.end(), output ); 51 52 // calculate sum of squares of elements of vector integers 53 // using binary function sumSquares 54 result = std::accumulate( integers.begin(), integers.end(), 55 0, sumSquares ); 56 57 cout << "nnSum of squares of elements in integers using " 58 << "binarynfunction sumSquares: " << result; 59 accumulate initially passes 0 as the first argument, with the first element as the second. It then uses the return value as the first argument, and iterates through the other elements.
416.
60 // calculatesum of squares of elements of vector integers 61 // using binary-function object 62 result = std::accumulate( integers.begin(), integers.end(), 63 0, SumSquaresClass< int >() ); 64 65 cout << "nnSum of squares of elements in integers using " 66 << "binarynfunction object of type " 67 << "SumSquaresClass< int >: " << result << endl; 68 69 return 0; 70 71 } // end main vector v contains: 1 2 3 4 5 6 7 8 9 10 Sum of squares of elements in integers using binary function sumSquares: 385 Sum of squares of elements in integers using binary function object of type SumSquaresClass< int >: 385 Use accumulate with a function object.
417.
Program Design andSoftware Tools Stack/Queue - File Processing Stack/Queue
418.
Introduction Storage ofdata Arrays, variables are temporary Files are permanent Magnetic disk, optical disk, tapes In this chapter Create, update, process files Sequential and random access Formatted and raw processing
419.
The Data Hierarchy From smallest to largest Bit (binary digit) 1 or 0 Character set Digits, letters, symbols used to represent data Every character represented by 1's and 0's Byte: 8 bits: Can store a character (char) From smallest to largest (continued) Field: group of characters with some meaning Your name Record: group of related fields struct or class in C++ In payroll system, could be name, SS#, address, wage Each field associated with same employee Record key: field used to uniquely identify record File: group of related records Payroll for entire company Sequential file: records stored by key Database: group of related files Payroll, accounts-receivable, inventory…
420.
Files and Streams C++ views file as sequence of bytes Ends with end-of-file marker When file opened Object created, stream associated with it cin, cout, etc. created when <iostream> included Communication between program and file/device 0 31 2 4 5 8 9 ... ... n-1 end-of-file marker 6 7
421.
Files and Streams To perform file processing Include <iostream> and <fstream> Class templates basic_ifstream (input) basic_ofstream (output) basic_fstream (I/O) typedefs for specializations that allow char I/O ifstream (char input) ofstream (char output) fstream (char I/O)
422.
Files and Streams Opening files Create objects from template Derive from stream classes Can use stream methods : put, get, peek, etc. basic_fstream basic_ios basic_ifstream basic_ofstreambasic_iostream basic_istream basic_ostream
423.
Creating a Sequential-AccessFile C++ imposes no structure on file Concept of "record" must be implemented by programmer To open file, create objects Creates "line of communication" from object to file Classes ifstream (input only) ofstream (output only) fstream (I/O) Constructors take file name and file-open mode ofstream outClientFile( "filename", fileOpenMode ); To attach a file later Ofstream outClientFile; outClientFile.open( "filename", fileOpenMode);
424.
Creating a Sequential-AccessFile File-open modes ofstream opened for output by default ofstream outClientFile( "clients.dat", ios::out ); ofstream outClientFile( "clients.dat"); Mode Description ios::app Write all output to the end of the file. ios::ate Open a file for output and move to the end of the file (normally used to append data to a file). Data can be written anywhere in the file. ios::in Open a file for input. ios::out Open a file for output. ios::trunc Discard the file’s contents if it exists (this is also the default action for ios::out) ios::binary Open a file for binary (i.e., non-text) input or output.
425.
Creating a Sequential-AccessFile Operations Overloaded operator! !outClientFile Returns nonzero (true) if badbit or failbit set Opened non-existent file for reading, wrong permissions Overloaded operator void* Converts stream object to pointer 0 when failbit or badbit set, otherwise nonzero failbit set when EOF found while ( cin >> myVariable ) Implicitly converts cin to pointer Loops until EOF Writing to file (just like cout) outClientFile << myVariable Closing file outClientFile.close() Automatically closed when destructor called
426.
1 // Example87 2 // Create a sequential file. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::ios; 8 using std::cerr; 9 using std::endl; 10 11 #include <fstream> 12 13 using std::ofstream; 14 15 #include <cstdlib> // exit prototype 16 17 int main() 18 { 19 // ofstream constructor opens file 20 ofstream outClientFile( "clients.dat", ios::out ); 21 22 // exit program if unable to create file 23 if ( !outClientFile ) { // overloaded ! operator 24 cerr << "File could not be opened" << endl; 25 exit( 1 ); 26 27 } // end if Notice the the header files required for file I/O. ofstream object created and used to open file "clients.dat". If the file does not exist, it is created. ! operator used to test if the file opened properly.
427.
28 29 cout <<"Enter the account, name, and balance." << endl 30 << "Enter end-of-file to end input.n? "; 31 32 int account; 33 char name[ 30 ]; 34 double balance; 35 36 // read account, name and balance from cin, then place in file 37 while ( cin >> account >> name >> balance ) { 38 outClientFile << account << ' ' << name << ' ' << balance 39 << endl; 40 cout << "? "; 41 42 } // end while 43 44 return 0; // ofstream destructor closes file 45 46 } // end main cin is implicitly converted to a pointer. When EOF is encountered, it returns 0 and the loop stops. Write data to file like a regular stream. File closed when destructor called for object. Can be explicitly closed with close().
428.
Enter the account,name, and balance. Enter end-of-file to end input. ? 100 Jones 24.98 ? 200 Doe 345.67 ? 300 White 0.00 ? 400 Stone -42.16 ? 500 Rich 224.62 ? ^Z
429.
Reading Data froma Sequential- Access File Reading files ifstream inClientFile( "filename", ios::in ); Overloaded ! !inClientFile tests if file was opened properly operator void* converts to pointer while (inClientFile >> myVariable) Stops when EOF found (gets value 0)
430.
28 int main() 29{ 30 // ifstream constructor opens the file 31 ifstream inClientFile( "clients.dat", ios::in ); 32 33 // exit program if ifstream could not open file 34 if ( !inClientFile ) { 35 cerr << "File could not be opened" << endl; 36 exit( 1 ); 37 38 } // end if 39 40 int account; 41 char name[ 30 ]; 42 double balance; 43 44 cout << left << setw( 10 ) << "Account" << setw( 13 ) 45 << "Name" << "Balance" << endl << fixed << showpoint; 46 47 // display each record in file 48 while ( inClientFile >> account >> name >> balance ) 49 outputLine( account, name, balance ); 50 51 return 0; // ifstream destructor closes the file 52 53 } // end main Open and test file for input. Read from file until EOF found.
431.
54 55 // displaysingle record from file 56 void outputLine( int account, const char * const name, 57 double balance ) 58 { 59 cout << left << setw( 10 ) << account << setw( 13 ) << name 60 << setw( 7 ) << setprecision( 2 ) << right << balance 61 << endl; 62 63 } // end function outputLine Account Name Balance 100 Jones 24.98 200 Doe 345.67 300 White 0.00 400 Stone -42.16 500 Rich 224.62
432.
Reading Data froma Sequential- Access File File position pointers Number of next byte to read/write Functions to reposition pointer seekg (seek get for istream class) seekp (seek put for ostream class) Classes have "get" and "put" pointers seekg and seekp take offset and direction Offset: number of bytes relative to direction Direction (ios::beg default) ios::beg - relative to beginning of stream ios::cur - relative to current position ios::end - relative to end
433.
Reading Data froma Sequential- Access File Examples fileObject.seekg(0) Goes to front of file (location 0) because ios::beg is default fileObject.seekg(n) Goes to nth byte from beginning fileObject.seekg(n, ios::cur) Goes n bytes forward fileObject.seekg(y, ios::end) Goes y bytes back from end fileObject.seekg(0, ios::cur) Goes to last byte seekp similar To find pointer location tellg and tellp location = fileObject.tellg()
434.
Updating Sequential-Access Files Updating sequential files Risk overwriting other data Example: change name "White" to "Worthington" Old data 300 White 0.00 400 Jones 32.87 Insert new data Formatted text different from internal representation Problem can be avoided, but awkward 300 White 0.00 400 Jones 32.87 300 Worthington 0.00ones 32.87 300 Worthington 0.00 Data gets overwritten
435.
Random-Access Files Instantaccess Want to locate record quickly Airline reservations, ATMs Sequential files must search through each one Random-access files are solution Instant access Insert record without destroying other data Update/delete items without changing other data
436.
Random-Access Files C++imposes no structure on files Programmer must create random-access files Simplest way: fixed-length records Calculate position in file from record size and key 0 200 300 400 500 byte offsets } } } } } } } 100 100 bytes 100 bytes 100 bytes 100 bytes 100 bytes 100 bytes
437.
Creating a Random-AccessFile "1234567" (char *) vs 1234567 (int) char * takes 8 bytes (1 for each character + null) int takes fixed number of bytes (perhaps 4) 123 same size in bytes as 1234567 << operator and write() outFile << number Outputs number (int) as a char * Variable number of bytes outFile.write( const char *, size ); Outputs raw bytes Takes pointer to memory location, number of bytes to write Copies data directly from memory into file Does not convert to char *
438.
Creating a Random-AccessFile Example outFile.write( reinterpret_cast<const char *>(&number), sizeof( number ) ); &number is an int * Convert to const char * with reinterpret_cast sizeof(number) Size of number (an int) in bytes read function similar (more later) Must use write/read between compatible machines Only when using raw, unformatted data Use ios::binary for raw writes/reads Usually write entire struct or object to file
439.
Writing Data Randomlyto a Random-Access File Use seekp to write to exact location in file Where does the first record begin? Byte 0 The second record? Byte 0 + sizeof(object) Any record? (Recordnum - 1) * sizeof(object) read - similar to write Reads raw bytes from file into memory inFile.read( reinterpret_cast<char *>( &number ), sizeof( int ) ); &number: location to store data sizeof(int): how many bytes to read Do not use inFile >> number with raw bytes >> expects char *
440.
Input/Output of Objects I/O of objects Chapter 8 (overloaded >>) Only object's data transmitted Member functions available internally When objects stored in file, lose type info (class, etc.) Program must know type of object when reading One solution When writing, output object type code before real object When reading, read type code Call proper overloaded function (switch)
Introduction Exceptions Indicatesproblem occurred in program Not common An "exception" to a program that usually works Exception Handling Resolve exceptions Program may be able to continue Controlled termination Write fault-tolerant programs
443.
Exception-Handling Overview Considerpseudocode Perform a task If the preceding task did not execute correctly Perform error processing Perform next task If the preceding task did not execute correctly Perform error processing Mixing logic and error handling Can make program difficult to read/debug Exception handling removes error correction from "main line" of program
444.
Exception-Handling Overview Exceptionhandling For synchronous errors (divide by zero, null pointer) Cannot handle asynchronous errors (independent of program) Disk I/O, mouse, keyboard, network messages Easy to handle errors Terminology Function that has error throws an exception Exception handler (if it exists) can deal with problem Catches and handles exception If no exception handler, uncaught exception Could terminate program
445.
Exception-Handling Overview C++code try { code that may raise exception } catch (exceptionType){ code to handle exception } try block encloses code that may raise exception One or more catch blocks follow Catch and handle exception, if appropriate Take parameter; if named, can access exception object
446.
Exception-Handling Overview Throwpoint Location in try block where exception occurred If exception handled Program skips remainder of try block Resumes after catch blocks If not handled Function terminates Looks for enclosing catch block (stack unwinding) If no exception Program skips catch blocks
447.
Other Error-Handling Techniques Ignore exception Typical for personal (not commercial) software Program may fail Abort program Usually appropriate Not appropriate for mission-critical software Set error indicators Unfortunately, may not test for these when necessary Test for error condition Call exit (<cstdlib>) and pass error code
448.
Other Error-Handling Techniques setjump and longjump <csetjmp> Jump from deeply nested function to call error handler Can be dangerous Dedicated error handling new can have a special handler
449.
Simple Exception-Handling Example: Divideby Zero Keyword throw Throws an exception Use when error occurs Can throw almost anything (exception object, integer, etc.) throw myObject; throw 5; Exception objects Base class runtime_error ( <stdexcept> ) Constructor can take a string (to describe exception) Member function what() returns that string
450.
Simple Exception-Handling Example: Divideby Zero Upcoming example Handle divide-by-zero errors Define new exception class DivideByZeroException Inherit from runtime_error In division function Test denominator If zero, throw exception (throw object) In try block Attempt to divide Have enclosing catch block Catch DivideByZeroException objects
451.
1 // Example88 2 // A simple exception-handling example that checks for 3 // divide-by-zero exceptions. 4 #include <iostream> 5 6 using std::cout; 7 using std::cin; 8 using std::endl; 9 10 #include <exception> 11 12 using std::exception; 13 14 // DivideByZeroException objects should be thrown by functions 15 // upon detecting division-by-zero exceptions 16 class DivideByZeroException : public runtime_error { 17 18 public: 19 20 // constructor specifies default error message 21 DivideByZeroException::DivideByZeroException() 22 : exception( "attempted to divide by zero" ) {} 23 24 }; // end class DivideByZeroException 25 Define new exception class (inherit from runtime_error ). Pass a descriptive message to the constructor.
452.
26 // performdivision and throw DivideByZeroException object if 27 // divide-by-zero exception occurs 28 double quotient( int numerator, int denominator ) 29 { 30 // throw DivideByZeroException if trying to divide by zero 31 if ( denominator == 0 ) 32 throw DivideByZeroException(); // terminate function 33 34 // return division result 35 return static_cast< double >( numerator ) / denominator; 36 37 } // end function quotient 38 39 int main() 40 { 41 int number1; // user-specified numerator 42 int number2; // user-specified denominator 43 double result; // result of division 44 45 cout << "Enter two integers (end-of-file to end): "; 46 If the denominator is zero, throw a DivideByZeroException object.
453.
47 // enableuser to enter two integers to divide 48 while ( cin >> number1 >> number2 ) { 49 50 // try block contains code that might throw exception 51 // and code that should not execute if an exception occurs 52 try { 53 result = quotient( number1, number2 ); 54 cout << "The quotient is: " << result << endl; 55 56 } // end try 57 58 // exception handler handles a divide-by-zero exception 59 catch ( DivideByZeroException ÷ByZeroException ) { 60 cout << "Exception occurred: " 61 << divideByZeroException.what() << endl; 62 63 } // end catch 64 65 cout << "nEnter two integers (end-of-file to end): "; 66 67 } // end while 68 69 cout << endl; 70 71 return 0; // terminate normally 72 73 } // end main Notice the structure of the try and catch blocks. The catch block can catch DivideByZeroException objects, and print an error message. If no exception occurs, the catch block is skipped. Member function what returns the string describing the exception.
454.
Enter two integers(end-of-file to end): 100 7 The quotient is: 14.2857 Enter two integers (end-of-file to end): 100 0 Exception occurred: attempted to divide by zero Enter two integers (end-of-file to end): ^Z
455.
Rethrowing an Exception Rethrowing exceptions Use when exception handler cannot process exception Can still rethrow if handler did some processing Can rethrow exception to another handler Goes to next enclosing try block Corresponding catch blocks try to handle To rethrow Use statement "throw;" No arguments Terminates function
456.
1 // Example89 2 // Demonstrating exception rethrowing. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <exception> 9 10 using std::exception; 11 12 // throw, catch and rethrow exception 13 void throwException() 14 { 15 // throw exception and catch it immediately 16 try { 17 cout << " Function throwException throws an exceptionn"; 18 throw exception(); // generate exception 19 20 } // end try 21 22 // handle exception 23 catch ( exception &caughtException ) { 24 cout << " Exception handled in function throwException" 25 << "n Function throwException rethrows exception"; 26 27 throw; // rethrow exception for further processing 28 29 } // end catch Exception handler generates a default exception (base class exception). It immediately catches and rethrows it (note use of throw;).
457.
30 31 cout <<"This also should not printn"; 32 33 } // end function throwException 34 35 int main() 36 { 37 // throw exception 38 try { 39 cout << "nmain invokes function throwExceptionn"; 40 throwException(); 41 cout << "This should not printn"; 42 43 } // end try 44 45 // handle exception 46 catch ( exception &caughtException ) { 47 cout << "nnException handled in mainn"; 48 49 } // end catch 50 51 cout << "Program control continues after catch in mainn"; 52 53 return 0; 54 55 } // end main This should never be reached, since the throw immediately exits the function. throwException rethrows an exception to main. It is caught and handled.
458.
main invokes functionthrowException Function throwException throws an exception Exception handled in function throwException Function throwException rethrows exception Exception handled in main Program control continues after catch in main
459.
Exception Specifications Listof exceptions function can throw Also called throw list int someFunction( double value ) throw ( ExceptionA, ExceptionB, ExceptionC ) { // function body } Can only throw ExceptionA, ExceptionB, and ExceptionC (and derived classes) If throws other type, function unexpected called By default, terminates program (more 13.7) If no throw list, can throw any exception If empty throw list, cannot throw any exceptions
460.
Processing Unexpected Exceptions Function unexpected Calls function registered with set_unexpected <exception> Calls terminate by default set_terminate Sets what function terminate calls By default, calls abort If redefined, still calls abort after new function finishes Arguments for set functions Pass pointer to function Function must take no arguments Returns void
461.
Stack Unwinding Ifexception thrown but not caught Goes to enclosing try block Terminates current function Unwinds function call stack Looks for try/catch that can handle exception If none found, unwinds again If exception never caught Calls terminate
462.
1 // Example90 2 // Demonstrating stack unwinding. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <stdexcept> 9 10 using std::runtime_error; 11 12 // function3 throws run-time error 13 void function3() throw ( runtime_error ) 14 { 15 throw runtime_error( "runtime_error in function3" ); // fourth 16 } 17 18 // function2 invokes function3 19 void function2() throw ( runtime_error ) 20 { 21 function3(); // third 22 } 23 Note the use of the throw list. Throws a runtime error exception, defined in <stdexcept>.
463.
24 // function1invokes function2 25 void function1() throw ( runtime_error ) 26 { 27 function2(); // second 28 } 29 30 // demonstrate stack unwinding 31 int main() 32 { 33 // invoke function1 34 try { 35 function1(); // first 36 37 } // end try 38 39 // handle run-time error 40 catch ( runtime_error &error ) // fifth 41 { 42 cout << "Exception occurred: " << error.what() << endl; 43 44 } // end catch 45 46 return 0; 47 48 } // end main Exception occurred: runtime_error in function3 function1 calls function2 which calls function3. The exception occurs, and unwinds until an appropriate try/catch block can be found.
464.
Constructors, Destructors andException Handling Error in constructor new fails; cannot allocate memory Cannot return a value - how to inform user? Hope user examines object, notices errors Set some global variable Good alternative: throw an exception Destructors automatically called for member objects Called for automatic variables in try block Can catch exceptions in destructor
465.
Exceptions and Inheritance Exception classes Can be derived from base classes I.e., runtime_error; exception If catch can handle base class, can handle derived classes Polymorphic programming
466.
Processing new Failures When new fails to get memory Should throw bad_alloc exception Defined in <new> Some compilers have new return 0 Result depends on compiler
467.
1 // Example91 2 // Demonstrating pre-standard new returning 0 when memory 3 // is not allocated. 4 #include <iostream> 5 6 using std::cout; 7 8 int main() 9 { 10 double *ptr[ 50 ]; 11 12 // allocate memory for ptr 13 for ( int i = 0; i < 50; i++ ) { 14 ptr[ i ] = new double[ 5000000 ]; 15 16 // new returns 0 on failure to allocate memory 17 if ( ptr[ i ] == 0 ) { 18 cout << "Memory allocation failed for ptr[ " 19 << i << " ]n"; 20 21 break; 22 23 } // end if 24 Demonstrating new that returns 0 on allocation failure.
468.
25 // successfulmemory allocation 26 else 27 cout << "Allocated 5000000 doubles in ptr[ " 28 << i << " ]n"; 29 30 } // end for 31 32 return 0; 33 34 } // end main Allocated 5000000 doubles in ptr[ 0 ] Allocated 5000000 doubles in ptr[ 1 ] Allocated 5000000 doubles in ptr[ 2 ] Allocated 5000000 doubles in ptr[ 3 ] Memory allocation failed for ptr[ 4 ]
469.
1 // Example92 2 // Demonstrating standard new throwing bad_alloc when memory 3 // cannot be allocated. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 #include <new> // standard operator new 10 11 using std::bad_alloc; 12 13 int main() 14 { 15 double *ptr[ 50 ]; 16 17 // attempt to allocate memory 18 try { 19 20 // allocate memory for ptr[ i ]; new throws bad_alloc 21 // on failure 22 for ( int i = 0; i < 50; i++ ) { 23 ptr[ i ] = new double[ 5000000 ]; 24 cout << "Allocated 5000000 doubles in ptr[ " 25 << i << " ]n"; 26 } 27 28 } // end try Demonstrating new that throws an exception.
Processing new Failures set_new_handler Header <new> Register function to call when new fails Takes function pointer to function that Takes no arguments Returns void Once registered, function called instead of throwing exception
472.
1 // Example93 2 // Demonstrating set_new_handler. 3 #include <iostream> 4 5 using std::cout; 6 using std::cerr; 7 8 #include <new> // standard operator new and set_new_handler 9 10 using std::set_new_handler; 11 12 #include <cstdlib> // abort function prototype 13 14 void customNewHandler() 15 { 16 cerr << "customNewHandler was called"; 17 abort(); 18 } 19 20 // using set_new_handler to handle failed memory allocation 21 int main() 22 { 23 double *ptr[ 50 ]; 24 The custom handler must take no arguments and return void.
473.
25 // specifythat customNewHandler should be called on failed 26 // memory allocation 27 set_new_handler( customNewHandler ); 28 29 // allocate memory for ptr[ i ]; customNewHandler will be 30 // called on failed memory allocation 31 for ( int i = 0; i < 50; i++ ) { 32 ptr[ i ] = new double[ 5000000 ]; 33 34 cout << "Allocated 5000000 doubles in ptr[ " 35 << i << " ]n"; 36 37 } // end for 38 39 return 0; 40 41 } // end main Allocated 5000000 doubles in ptr[ 0 ] Allocated 5000000 doubles in ptr[ 1 ] Allocated 5000000 doubles in ptr[ 2 ] Allocated 5000000 doubles in ptr[ 3 ] customNewHandler was called Note call to set_new_handler.
474.
Class auto_ptr andDynamic Memory Allocation Declare pointer, allocate memory with new What if exception occurs before you can delete it? Memory leak Template class auto_ptr Header <memory> Like regular pointers (has * and ->) When pointer goes out of scope, calls delete Prevents memory leaks Usage auto_ptr< MyClass > newPointer( new MyClass() ); newPointer points to dynamically allocated object
475.
1 // Example94 2 // Demonstrating auto_ptr. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <memory> 9 10 using std::auto_ptr; // auto_ptr class definition 11 12 class Integer { 13 14 public: 15 16 // Integer constructor 17 Integer( int i = 0 ) 18 : value( i ) 19 { 20 cout << "Constructor for Integer " << value << endl; 21 22 } // end Integer constructor 23
476.
24 // Integerdestructor 25 ~Integer() 26 { 27 cout << "Destructor for Integer " << value << endl; 28 29 } // end Integer destructor 30 31 // function to set Integer 32 void setInteger( int i ) 33 { 34 value = i; 35 36 } // end function setInteger 37 38 // function to return Integer 39 int getInteger() const 40 { 41 return value; 42 43 } // end function getInteger 44 45 private: 46 int value; 47 48 }; // end class Integer 49
477.
50 // useauto_ptr to manipulate Integer object 51 int main() 52 { 53 cout << "Creating an auto_ptr object that points to an " 54 << "Integern"; 55 56 // "aim" auto_ptr at Integer object 57 auto_ptr< Integer > ptrToInteger( new Integer( 7 ) ); 58 59 cout << "nUsing the auto_ptr to manipulate the Integern"; 60 61 // use auto_ptr to set Integer value 62 ptrToInteger->setInteger( 99 ); 63 64 // use auto_ptr to get Integer value 65 cout << "Integer after setInteger: " 66 << ( *ptrToInteger ).getInteger() 67 << "nnTerminating program" << endl; 68 69 return 0; 70 71 } // end main Create an auto_ptr. It can be manipulated like a regular pointer. delete not explicitly called, but the auto_ptr will be destroyed once it leaves scope. Thus, the destructor for class Integer will be called.
478.
Creating an auto_ptrobject that points to an Integer Constructor for Integer 7 Using the auto_ptr to manipulate the Integer Integer after setInteger: 99 Terminating program Destructor for Integer 99
479.
Standard Library ExceptionHierarchy Exception hierarchy Base class exception (<exception>) Virtual function what, overridden to provide error messages Sample derived classes runtime_error, logic_error bad_alloc, bad_cast, bad_typeid Thrown by new, dynamic_cast and typeid To catch all exceptions catch(...) catch( exception AnyException) Will not catch user-defined exceptions
Preprocessing Preprocessing Occursbefore program compiled Inclusion of external files Definition of symbolic constants Macros Conditional compilation Conditional execution pf preprocessing directive All directives begin with # Can only have whitespace before directives Directives not C++ statements Do not end with ;
482.
The #include Preprocessor Directive #include directive Puts copy of file in place of directive Two forms #include <filename> For standard library header files Searches pre-designated directories #include "filename" Searches in current directory Normally used for programmer-defined files Usage Loading header files #include <iostream> Programs with multiple source files Header file Has common declarations and definitions Classes, structures, enumerations, function prototypes Extract commonality of multiple program files
483.
The #define Preprocessor Directive:Symbolic Constants #define Symbolic constants Constants represented as symbols When program compiled, all occurrences replaced Format #define identifier replacement-text #define PI 3.14159 Everything to right of identifier replaces text #define PI=3.14159 Replaces PI with "=3.14159" Probably an error Cannot redefine symbolic constants Advantage: Takes no memory Disadvantages Name not seen by debugger (only replacement text) Do not have specific data type const variables preferred
484.
The #define Preprocessor Directive:Macros Macro Operation specified in #define Macro without arguments Treated like a symbolic constant Macro with arguments Arguments substituted for replacement text Macro expanded Performs a text substitution No data type checking
485.
The #define Preprocessor Directive:Macros Example #define CIRCLE_AREA( x ) ( PI * ( x ) * ( x ) ) area = CIRCLE_AREA( 4 ); becomes area = ( 3.14159 * ( 4 ) * ( 4 ) ); Use parentheses Without them, #define CIRCLE_AREA( x ) PI * x * x area = CIRCLE_AREA( c + 2 ); becomes area = 3.14159 * c + 2 * c + 2; which evaluates incorrectly
486.
The #define Preprocessor Directive:Macros Multiple arguments #define RECTANGLE_AREA( x, y ) ( ( x ) * ( y ) ) rectArea = RECTANGLE_AREA( a + 4, b + 7 ); becomes rectArea = ( ( a + 4 ) * ( b + 7 ) ); #undef Undefines symbolic constant or macro Can later be redefined
487.
Conditional Compilation Controlpreprocessor directives and compilation Cannot evaluate cast expressions, sizeof, enumeration constants Structure similar to if #if !defined( NULL ) #define NULL 0 #endif Determines if symbolic constant NULL defined If NULL defined, defined( NULL ) evaluates to 1 #define statement skipped Otherwise #define statement used Every #if ends with #endif
488.
Conditional Compilation Canuse else #else #elif is "else if" Abbreviations #ifdef short for #if defined(name) #ifndef short for #if !defined(name) "Comment out" code Cannot use /* ... */ with C-style comments Cannot nest /* */ Instead, use #if 0 code commented out #endif To enable code, change 0 to 1
489.
Conditional Compilation Debugging #defineDEBUG 1 #ifdef DEBUG cerr << "Variable x = " << x << endl; #endif Defining DEBUG enables code After code corrected Remove #define statement Debugging statements are now ignored
490.
The #error and#pragma Preprocessor Directives #error tokens Prints implementation-dependent message Tokens are groups of characters separated by spaces #error 1 - Out of range error has 6 tokens Compilation may stop (depends on compiler) #pragma tokens Actions depend on compiler May use compiler-specific options Unrecognized #pragmas are ignored
491.
The # and## Operators # operator Replacement text token converted to string with quotes #define HELLO( x ) cout << "Hello, " #x << endl; HELLO( JOHN ) becomes cout << "Hello, " "John" << endl; Same as cout << "Hello, John" << endl; ## operator Concatenates two tokens #define TOKENCONCAT( x, y ) x ## y TOKENCONCAT( O, K ) becomes OK
492.
Line Numbers #line Renumbers subsequent code lines, starting with integer #line 100 File name can be included #line 100 "file1.cpp" Next source code line is numbered 100 For error purposes, file name is "file1.cpp" Can make syntax errors more meaningful Line numbers do not appear in source file
493.
Predefined Symbolic Constants Fivepredefined symbolic constants Cannot be used in #define or #undef Symbolic constant Description __LINE__ The line number of the current source code line (an integer constant). __FILE__ The presumed name of the source file (a string). __DATE__ The date the source file is compiled (a string of the form "Mmm dd yyyy" such as "Jan 19 2001"). __TIME__ The time the source file is compiled (a string literal of the form "hh:mm:ss").
494.
Assertions assert isa macro Header <cassert> Tests value of an expression If 0 (false) prints error message, calls abort Terminates program, prints line number and file Good for checking for illegal values If 1 (true), program continues as normal assert( x <= 10 ); To remove assert statements No need to delete them manually #define NDEBUG All subsequent assert statements ignored
495.
Program Design andSoftware Tools Unified Modeling Language Unified Modeling Language
496.
What is UML? TheUnified Modelling Language is a standard notation to model [object oriented] systems. Syntax and semantics Model systems Visual documentations Collections of best practices Used to produce a set of artifacts that can be delivered Wide support Independent of programming languages Support high level concepts
Use Cases Ause case is a pattern of behavior the system exhibits Each use case is a sequence of related transactions performed by an actor and the system in a dialogue Actors are examined to determine their needs Registrar -- maintain the curriculum Professor -- request roster Student -- maintain schedule Maintain ScheduleMaintain Curriculum Request Course Roster
500.
Use Case Diagram Use case diagrams are created to visualize the relationships between actors and use cases Student Registrar Professor Maintain Schedule Maintain Curriculum Request Course Roster Billing System
501.
Use Case Realizations The use case diagram presents an outside view of the system Interaction diagrams describe how use cases are realized as interactions among societies of objects Two types of interaction diagrams Sequence diagrams Collaboration diagrams
502.
Class Diagram Class diagramsare the most commonly used diagrams in UML. Class diagrams are for visualizing, specifying and documenting the system from a static perspective. Class diagrams indicate which classes know about other classes and, if they do, what type of relationship exists. Class diagrams will have different levels of detail (abstraction) depending on where we are in the software development process.
503.
Class Diagrams Class diagramsdescribe types of objects in a system and their relationships. There are three types of relationships between classes: • Dependency (“uses”) • Aggregation (“has”) • Inheritance (“is”) Class diagrams also show the attributes and operations of a class.
Convention Name of classis a word with initial upper case letter Capitalize first letter of every word in name Name of attributes is lower case letter Capitalize first letter of every word other than first Operations have same naming schemes as attributes Brackets include parameter operation works on
Class Derived fromthe CRC Cards Sections: name, attributes, operations Construct Description Syntax class a description of a set of objects that share the same attributes, operations, methods, relationships and semantics. Name Attributes Methods
512.
Association It ismore important to identify classes than to identify associations Too many associations can be confusing Classes may have association with themselves person manages 1* Construct Description Syntax association a relationship between two or more classifiers that involves connections among their instances.
Aggregation A composite aggregation(filled diamond) means that the multiplicity at the composite end may be at most one. Shared aggregation (hollow diamond) means that the multiplicity at the composite end may be more than one. Construct Description Syntax aggregation A special form of association that specifies a whole-part relationship between the aggregate (whole) and the component part.
515.
Aggregation Guidelines There isan obvious physical or logical assembly The part and composite have the same lifetime Operations applied to the composite propagate to the parts e.g. destruction, movement, etc.
Classifier A classifier isa mechanism that describes structural and behavioral features. Types of classifiers are … classes, interfaces, datatypes, signals, components, nodes, use cases and subsystems. Classes are the most important kind of classifier. Classes have a number of features beyond attributes and behaviors that allow you to model some of the more subtle/advanced features of a system.
Template Icon Aparameterized element. Represented in UML as a dashed box in the upper right- hand corner of the class icon, which lists the template parameters.
Sequence Diagram Asequence diagram displays object interactions arranged in a time sequence : Student registration form registration manager math 101 1: fill in info 2: submit 3: add course(joe, math 01) 4: are you open? 5: are you open? 6: add (joe) 7: add (joe) math 101 section 1
523.
: Registrar course form: CourseForm theManager : CurriculumManager aCourse : Course 1: set course info 2: process 3: add course 4: new course Collaboration Diagram A collaboration diagram displays object interactions organized around objects and their links to one another
524.
The Physical World Component diagrams illustrate the organizations and dependencies among software components A component may be A source code component A run time components or An executable component
Deploying the System The deployment diagram shows the configuration of run-time processing elements and the software processes living on them The deployment diagram visualizes the distribution of components across the enterprise.
Review topics 1. Lvalue/rvalue 2.Reference variable + Calling functions by reference 3. Passing arrays to functions 4. Function pointers 5. Arrays of pointers to functions (e.g. menus) 6. Using member selection operators ('.' '->') 7. Returning a reference to a private data member 8. *this pointer 1. implicit & explicit use of *this pointer 2. *this pointer & cascaded function calls 9. When are destructors used, why not yet in the classes we're creating? 10. When is it appropriate to use 'new' and 'delete' from the <new> library? 11. Classes? 12. Polymorphism? 13. Multiple Inheritance?
529.
Confusing Equality (==)and Assignment (=) Operators Lvalues Expressions that can appear on left side of equation Can be changed x = 4; Rvalues Only appear on right side of equation Constants, such as numbers (i.e. cannot write 4 = x;) Lvalues can be used as rvalues, but not vice versa
530.
References and Reference Parameters Call by value Copy of data passed to function Changes to copy do not change original Prevent unwanted side effects Call by reference Function can directly access data Changes affect original Reference parameter Alias for argument in function call Passes parameter by reference Use & after data type in prototype void myFunction( int &data ) Read “data is a reference to an int” Function call format the same However, original can now be changed
531.
References and Reference Parameters Pointers Another way to pass-by-refernce References as aliases to other variables Refer to same variable Can be used within a function int count = 1; // declare integer variable count int &cRef = count; // create cRef as an alias for count ++cRef; // increment count (using its alias) References must be initialized when declared Otherwise, compiler error Dangling reference Reference to undefined variable
532.
Passing Arrays toFunctions Specify name without brackets To pass array myArray to myFunction int myArray[ 24 ]; myFunction( myArray, 24 ); Array size usually passed, but not required Useful to iterate over all elements Arrays passed-by-reference Functions can modify original array data Value of name of array is address of first element Function knows where the array is stored Can change original memory locations
533.
Passing Arrays toFunctions Functions taking arrays Function prototype void modifyArray( int b[], int arraySize ); void modifyArray( int [], int ); Names optional in prototype Both take an integer array and a single integer No need for array size between brackets Ignored by compiler If declare array parameter as const Cannot be modified (compiler error) void doNotModify( const int [] );
534.
Using const withPointers const qualifier Value of variable should not be modified const used when function does not need to change a variable Principle of least privilege const pointers Always point to same memory location Default for array name Must be initialized when declared Four ways to pass pointer to function Nonconstant pointer to nonconstant data Highest amount of access Nonconstant pointer to constant data Constant pointer to nonconstant data Constant pointer to constant data Least amount of access
535.
1 // Example95 2 // Attempting to modify a constant pointer to 3 // non-constant data. 4 5 int main() 6 { 7 int x, y; 8 9 // ptr is a constant pointer to an integer that can 10 // be modified through ptr, but ptr always points to the 11 // same memory location. 12 int * const ptr = &x; 13 14 *ptr = 7; // allowed: *ptr is not const 15 ptr = &y; // error: ptr is const; cannot assign new address 16 17 return 0; // indicates successful termination 18 19 } // end main ptr is constant pointer to integer.Can modify x (pointed to by ptr) since x not constant.Cannot modify ptr to point to new address since ptr is constant. Line 15 generates compiler error by attempting to assign new address to constant pointer. d:cpphtp4_examplesch05Fig05_13.cpp(15) : error C2166: l-value specifies const object
536.
1 // Example96 2 // Attempting to modify a constant pointer to constant data. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 int main() 9 { 10 int x = 5, y; 11 12 // ptr is a constant pointer to a constant integer. 13 // ptr always points to the same location; the integer 14 // at that location cannot be modified. 15 const int *const ptr = &x; 16 17 cout << *ptr << endl; 18 19 *ptr = 7; // error: *ptr is const; cannot assign new value 20 ptr = &y; // error: ptr is const; cannot assign new address 21 22 return 0; // indicates successful termination 23 24 } // end main ptr is constant pointer to integer constant. Cannot modify x (pointed to by ptr) since *ptr declared constant. Cannot modify ptr to point to new address since ptr is constant.
537.
Relationship Between Pointers andArrays Arrays and pointers closely related Array name like constant pointer Pointers can do array subscripting operations Accessing array elements with pointers Element b[ n ] can be accessed by *( bPtr + n ) Called pointer/offset notation Addresses &b[ 3 ] same as bPtr + 3 Array name can be treated as pointer b[ 3 ] same as *( b + 3 ) Pointers can be subscripted (pointer/subscript notation) bPtr[ 3 ] same as b[ 3 ]
538.
Function Pointers Callingfunctions using pointers Assume parameter: bool ( *compare ) ( int, int ) Execute function with either ( *compare ) ( int1, int2 ) Dereference pointer to function to execute OR compare( int1, int2 ) Could be confusing User may think compare name of actual function in program
539.
1 //Example 97 2// Multipurpose sorting program using function pointers. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 #include <iomanip> 10 11 using std::setw; 12 13 // prototypes 14 void bubble( int [], const int, bool (*)( int, int ) ); 15 void swap( int * const, int * const ); 16 bool ascending( int, int ); 17 bool descending( int, int ); 18 19 int main() 20 { 21 const int arraySize = 10; 22 int order; 23 int counter; 24 int a[ arraySize ] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 }; 25 Parameter is pointer to function that receives two integer parameters and returns bool result.
540.
26 cout <<"Enter 1 to sort in ascending order,n" 27 << "Enter 2 to sort in descending order: "; 28 cin >> order; 29 cout << "nData items in original ordern"; 30 31 // output original array 32 for ( counter = 0; counter < arraySize; counter++ ) 33 cout << setw( 4 ) << a[ counter ]; 34 35 // sort array in ascending order; pass function ascending 36 // as an argument to specify ascending sorting order 37 if ( order == 1 ) { 38 bubble( a, arraySize, ascending ); 39 cout << "nData items in ascending ordern"; 40 } 41 42 // sort array in descending order; pass function descending 43 // as an agrument to specify descending sorting order 44 else { 45 bubble( a, arraySize, descending ); 46 cout << "nData items in descending ordern"; 47 } 48
541.
49 // outputsorted array 50 for ( counter = 0; counter < arraySize; counter++ ) 51 cout << setw( 4 ) << a[ counter ]; 52 53 cout << endl; 54 55 return 0; // indicates successful termination 56 57 } // end main 58 59 // multipurpose bubble sort; parameter compare is a pointer to 60 // the comparison function that determines sorting order 61 void bubble( int work[], const int size, 62 bool (*compare)( int, int ) ) 63 { 64 // loop to control passes 65 for ( int pass = 1; pass < size; pass++ ) 66 67 // loop to control number of comparisons per pass 68 for ( int count = 0; count < size - 1; count++ ) 69 70 // if adjacent elements are out of order, swap them 71 if ( (*compare)( work[ count ], work[ count + 1 ] ) ) 72 swap( &work[ count ], &work[ count + 1 ] ); compare is pointer to function that receives two integer parameters and returns bool result. Parentheses necessary to indicate pointer to function Call passed function compare; dereference pointer to execute function.
542.
73 74 } //end function bubble 75 76 // swap values at memory locations to which 77 // element1Ptr and element2Ptr point 78 void swap( int * const element1Ptr, int * const element2Ptr ) 79 { 80 int hold = *element1Ptr; 81 *element1Ptr = *element2Ptr; 82 *element2Ptr = hold; 83 84 } // end function swap 85 86 // determine whether elements are out of order 87 // for an ascending order sort 88 bool ascending( int a, int b ) 89 { 90 return b < a; // swap if b is less than a 91 92 } // end function ascending 93
543.
94 // determinewhether elements are out of order 95 // for a descending order sort 96 bool descending( int a, int b ) 97 { 98 return b > a; // swap if b is greater than a 99 100 } // end function descending Enter 1 to sort in ascending order, Enter 2 to sort in descending order: 1 Data items in original order 2 6 4 8 10 12 89 68 45 37 Data items in ascending order 2 4 6 8 10 12 37 45 68 89 Enter 1 to sort in ascending order, Enter 2 to sort in descending order: 2 Data items in original order 2 6 4 8 10 12 89 68 45 37 Data items in descending order 89 68 45 37 12 10 8 6 4 2
544.
Function Pointers Arraysof pointers to functions Menu-driven systems Pointers to each function stored in array of pointers to functions All functions must have same return type and same parameter types Menu choice subscript into array of function pointers
545.
1 // Example98 2 // Demonstrating an array of pointers to functions. 3 #include <iostream> 4 5 using std::cout; 6 using std::cin; 7 using std::endl; 8 9 // function prototypes 10 void function1( int ); 11 void function2( int ); 12 void function3( int ); 13 14 int main() 15 { 16 // initialize array of 3 pointers to functions that each 17 // take an int argument and return void 18 void (*f[ 3 ])( int ) = { function1, function2, function3 }; 19 20 int choice; 21 22 cout << "Enter a number between 0 and 2, 3 to end: "; 23 cin >> choice; 24 Array initialized with names of three functions; function names are pointers.
546.
25 // processuser's choice 26 while ( choice >= 0 && choice < 3 ) { 27 28 // invoke function at location choice in array f 29 // and pass choice as an argument 30 (*f[ choice ])( choice ); 31 32 cout << "Enter a number between 0 and 2, 3 to end: "; 33 cin >> choice; 34 } 35 36 cout << "Program execution completed." << endl; 37 38 return 0; // indicates successful termination 39 40 } // end main 41 42 void function1( int a ) 43 { 44 cout << "You entered " << a 45 << " so function1 was callednn"; 46 47 } // end function1 48 Call chosen function by dereferencing corresponding element in array.
547.
49 void function2(int b ) 50 { 51 cout << "You entered " << b 52 << " so function2 was callednn"; 53 54 } // end function2 55 56 void function3( int c ) 57 { 58 cout << "You entered " << c 59 << " so function3 was callednn"; 60 61 } // end function3 Enter a number between 0 and 2, 3 to end: 0 You entered 0 so function1 was called Enter a number between 0 and 2, 3 to end: 1 You entered 1 so function2 was called Enter a number between 0 and 2, 3 to end: 2 You entered 2 so function3 was called Enter a number between 0 and 2, 3 to end: 3 Program execution completed.
548.
Accessing Structure Members Member access operators Dot operator (.) for structure and class members Arrow operator (->) for structure and class members via pointer to object Print member hour of timeObject: cout << timeObject.hour; OR timePtr = &timeObject; cout << timePtr->hour; timePtr->hour same as ( *timePtr ).hour Parentheses required * lower precedence than .
549.
Subtle Trap: Returninga Reference to a private Data Member Reference to object &pRef = p; Alias for name of object Lvalue Can receive value in assignment statement Changes original object Returning references public member functions can return non-const references to private data members Client able to modify private data members
550.
1 // Example99 2 // Declaration of class Time. 3 // Member functions defined in time4.cpp 4 5 // prevent multiple inclusions of header file 6 #ifndef TIME4_H 7 #define TIME4_H 8 9 class Time { 10 11 public: 12 Time( int = 0, int = 0, int = 0 ); 13 void setTime( int, int, int ); 14 int getHour(); 15 16 int &badSetHour( int ); // DANGEROUS reference return 17 18 private: 19 int hour; 20 int minute; 21 int second; 22 23 }; // end class Time 24 25 #endif Function to demonstrate effects of returning reference to private data member.
551.
25 // returnhour value 26 int Time::getHour() 27 { 28 return hour; 29 30 } // end function getHour 31 32 // POOR PROGRAMMING PRACTICE: 33 // Returning a reference to a private data member. 34 int &Time::badSetHour( int hh ) 35 { 36 hour = ( hh >= 0 && hh < 24 ) ? hh : 0; 37 38 return hour; // DANGEROUS reference return 39 40 } // end function badSetHour Return reference to private data member hour.
552.
1 // Example100 2 // Demonstrating a public member function that 3 // returns a reference to a private data member. 4 #include <iostream> 5 6 using std::cout; 7 using std::endl; 8 9 // include definition of class Time from time4.h 10 #include "time4.h" 11 12 int main() 13 { 14 Time t; 15 16 // store in hourRef the reference returned by badSetHour 17 int &hourRef = t.badSetHour( 20 ); 18 19 cout << "Hour before modification: " << hourRef; 20 21 // use hourRef to set invalid value in Time object t 22 hourRef = 30; 23 24 cout << "nHour after modification: " << t.getHour(); 25 badSetHour returns reference to private data member hour. Reference allows setting of private data member hour.
553.
26 // Dangerous:Function call that returns 27 // a reference can be used as an lvalue! 28 t.badSetHour( 12 ) = 74; 29 30 cout << "nn*********************************n" 31 << "POOR PROGRAMMING PRACTICE!!!!!!!!n" 32 << "badSetHour as an lvalue, Hour: " 33 << t.getHour() 34 << "n*********************************" << endl; 35 36 return 0; 37 38 } // end main Hour before modification: 20 Hour after modification: 30 ********************************* POOR PROGRAMMING PRACTICE!!!!!!!! badSetHour as an lvalue, Hour: 74 ********************************* Can use function call as lvalue to set invalid value. Returning reference allowed invalid setting of private data member hour.
554.
Default Memberwise Assignment Assigning objects Assignment operator (=) Can assign one object to another of same type Default: memberwise assignment Each right member assigned individually to left member Passing, returning objects Objects passed as function arguments Objects returned from functions Default: pass-by-value Copy of object passed, returned Copy constructor Copy original values into new object
555.
Dynamic Memory Management withOperators new and delete Dynamic memory management Control allocation and deallocation of memory Operators new and delete Include standard header <new> new Time *timePtr; timePtr = new Time; Creates object of proper size for type Time Error if no space in memory for object Calls default constructor for object Returns pointer of specified type Providing initializers double *ptr = new double( 3.14159 ); Time *timePtr = new Time( 12, 0, 0 ); Allocating arrays int *gradesArray = new int[ 10 ];
556.
Dynamic Memory Managementwith Operators new and delete delete Destroy dynamically allocated object and free space Consider delete timePtr; Operator delete Calls destructor for object Deallocates memory associated with object Memory can be reused to allocate other objects Deallocating arrays delete [] gradesArray; Deallocates array to which gradesArray points If pointer to array of objects First calls destructor for each object in array Then deallocates memory
557.
employee2.h (2 of2) employee2.cpp (1 of 3) 1 // Example 102 2 // Member-function definitions for class Employee. 3 #include <iostream> 4 5 using std::cout; 6 using std::endl; 7 8 #include <new> // C++ standard new operator 9 #include <cstring> // strcpy and strlen prototypes 10 11 #include "employee2.h" // Employee class definition 12 13 // define and initialize static data member 14 int Employee::count = 0; 15 16 // define static member function that returns number of 17 // Employee objects instantiated 18 int Employee::getCount() 19 { 20 return count; 21 22 } // end static function getCount Initialize static data member exactly once at file scope. static member function accesses static data member count.
558.
static Class Members static class variable “Class-wide” data Property of class, not specific object of class Efficient when single copy of data is enough Only the static variable has to be updated May seem like global variables, but have class scope Only accessible to objects of same class Initialized exactly once at file scope Exist even if no objects of class exist Can be public, private or protected
559.
static Class Members Accessing static class variables Accessible through any object of class public static variables Can also be accessed using binary scope resolution operator(::) Employee::count private static variables When no class member objects exist: Can only be accessed via public static member function Employee::getCount() static member functions Cannot access non-static data or functions No this pointer for static functions static data members and static member functions exist independent of objects
560.
1 // Example101 2 // Employee class definition. 3 #ifndef EMPLOYEE2_H 4 #define EMPLOYEE2_H 5 6 class Employee { 7 8 public: 9 Employee( const char *, const char * ); // constructor 10 ~Employee(); // destructor 11 const char *getFirstName() const; // return first name 12 const char *getLastName() const; // return last name 13 14 // static member function 15 static int getCount(); // return # objects instantiated 16 17 private: 18 char *firstName; 19 char *lastName; 20 21 // static data member 22 static int count; // number of objects instantiated 23 24 }; // end class Employee 25 static member function can only access static data members and member functions. static data member is class-wide data.
561.
23 24 // constructordynamically allocates space for 25 // first and last name and uses strcpy to copy 26 // first and last names into the object 27 Employee::Employee( const char *first, const char *last ) 28 { 29 firstName = new char[ strlen( first ) + 1 ]; 30 strcpy( firstName, first ); 31 32 lastName = new char[ strlen( last ) + 1 ]; 33 strcpy( lastName, last ); 34 35 ++count; // increment static count of employees 36 37 cout << "Employee constructor for " << firstName 38 << ' ' << lastName << " called." << endl; 39 40 } // end Employee constructor 41 42 // destructor deallocates dynamically allocated memory 43 Employee::~Employee() 44 { 45 cout << "~Employee() called for " << firstName 46 << ' ' << lastName << endl; 47 new operator dynamically allocates space. Use static data member to store total count of employees.
562.
48 delete []firstName; // recapture memory 49 delete [] lastName; // recapture memory 50 51 --count; // decrement static count of employees 52 53 } // end destructor ~Employee 54 55 // return first name of employee 56 const char *Employee::getFirstName() const 57 { 58 // const before return type prevents client from modifying 59 // private data; client should copy returned string before 60 // destructor deletes storage to prevent undefined pointer 61 return firstName; 62 63 } // end function getFirstName 64 65 // return last name of employee 66 const char *Employee::getLastName() const 67 { 68 // const before return type prevents client from modifying 69 // private data; client should copy returned string before 70 // destructor deletes storage to prevent undefined pointer 71 return lastName; 72 73 } // end function getLastName Operator delete deallocates memory. Use static data member to store total count of employees.
563.
Operator Functions AsClass Members Vs. As Friend Functions Operator functions Member functions Use this keyword to implicitly get argument Gets left operand for binary operators (like +) Leftmost object must be of same class as operator Non member functions Need parameters for both operands Can have object of different class than operator Must be a friend to access private or protected data Example Overloaded << operator Left operand of type ostream & Such as cout object in cout << classObject Similarly, overloaded >> needs istream & Thus, both must be non-member functions
564.
Operator Functions AsClass Members Vs. As Friend Functions Commutative operators May want + to be commutative So both “a + b” and “b + a” work Suppose we have two different classes Overloaded operator can only be member function when its class is on left HugeIntClass + Long int Can be member function When other way, need a non-member overload function Long int + HugeIntClass
565.
Overloading Stream-Insertion and Stream-ExtractionOperators << and >> Already overloaded to process each built-in type Can also process a user-defined class Example program Class PhoneNumber Holds a telephone number Print out formatted number automatically (123) 456-7890
566.
1 // Example103 2 // Overloading the stream-insertion and 3 // stream-extraction operators. 4 #include <iostream> 5 6 using std::cout; 7 using std::cin; 8 using std::endl; 9 using std::ostream; 10 using std::istream; 11 12 #include <iomanip> 13 14 using std::setw; 15 16 // PhoneNumber class definition 17 class PhoneNumber { 18 friend ostream &operator<<( ostream&, const PhoneNumber & ); 19 friend istream &operator>>( istream&, PhoneNumber & ); 20 21 private: 22 char areaCode[ 4 ]; // 3-digit area code and null 23 char exchange[ 4 ]; // 3-digit exchange and null 24 char line[ 5 ]; // 4-digit line and null 25 26 }; // end class PhoneNumber Notice function prototypes for overloaded operators >> and << They must be non-member friend functions, since the object of class Phonenumber appears on the right of the operator. cin << object cout >> object
567.
27 28 // overloadedstream-insertion operator; cannot be 29 // a member function if we would like to invoke it with 30 // cout << somePhoneNumber; 31 ostream &operator<<( ostream &output, const PhoneNumber &num ) 32 { 33 output << "(" << num.areaCode << ") " 34 << num.exchange << "-" << num.line; 35 36 return output; // enables cout << a << b << c; 37 38 } // end function operator<< 39 40 // overloaded stream-extraction operator; cannot be 41 // a member function if we would like to invoke it with 42 // cin >> somePhoneNumber; 43 istream &operator>>( istream &input, PhoneNumber &num ) 44 { 45 input.ignore(); // skip ( 46 input >> setw( 4 ) >> num.areaCode; // input area code 47 input.ignore( 2 ); // skip ) and space 48 input >> setw( 4 ) >> num.exchange; // input exchange 49 input.ignore(); // skip dash (-) 50 input >> setw( 5 ) >> num.line; // input line 51 52 return input; // enables cin >> a >> b >> c; The expression: cout << phone; is interpreted as the function call: operator<<(cout, phone); output is an alias for cout. This allows objects to be cascaded. cout << phone1 << phone2; first calls operator<<(cout, phone1), and returns cout. Next, cout << phone2 executes. Stream manipulator setw restricts number of characters read. setw(4) allows 3 characters to be read, leaving room for the null character.
568.
53 54 } //end function operator>> 55 56 int main() 57 { 58 PhoneNumber phone; // create object phone 59 60 cout << "Enter phone number in the form (123) 456-7890:n"; 61 62 // cin >> phone invokes operator>> by implicitly issuing 63 // the non-member function call operator>>( cin, phone ) 64 cin >> phone; 65 66 cout << "The phone number entered was: " ; 67 68 // cout << phone invokes operator<< by implicitly issuing 69 // the non-member function call operator<<( cout, phone ) 70 cout << phone << endl; 71 72 return 0; 73 74 } // end main Enter phone number in the form (123) 456-7890: (800) 555-1212 The phone number entered was: (800) 555-1212