C++ Programming: Program Design Including Data Structures, Fourth Edition 13-1 Chapter 13 Pointers, Classes, Virtual Functions, and Abstract Classes At a Glance Instructor’s Manual Table of Contents Overview Objectives Teaching Tips Quick Quizzes Class Discussion Topics Additional Projects Additional Resources Key Terms C++ Programming: Program Design Including Data Structures, Fourth Edition 13-2 Lecture Notes Overview Recall that C++ data types are classified into three categories: simple, structured, and pointers. Chapter 13 introduces students to the pointer data type. Students will learn how to declare and manipulate pointers. They will explore how to work with dynamic variables and arrays, and examine the issues involved with using pointers as member variables in classes. Students will also be introduced to additional object-oriented techniques, including virtual functions and abstract classes. Objectives In this chapter, the student will: Learn about the pointer data type and pointer variables Explore how to declare and manipulate pointer variables Learn about the address of operator and the dereferencing operator Discover dynamic variables Explore how to use the new and delete operators to manipulate dynamic variables Learn about pointer arithmetic Discover dynamic arrays Become aware of the shallow and deep copies of data Discover the peculiarities of classes with pointer member variables Learn about virtual functions Examine the relationship between the address of operator and classes Become aware of abstract classes Teaching Tips Pointer Data Type and Pointer Variables 1. Define the term pointer variable and explain its purpose in C++. Teaching Tip Plan to spend quite a bit of time introducing pointers. C++ offers low-level programmer management of memory; students may not have had previous experience with this unless they have worked with the C programming language. Pointer terminology will most likely be confusing and initially frustrating for your students. C++ Programming: Program Design Including Data Structures, Fourth Edition 13-3 Declaring Pointer Variables 1. Emphasize that there is no name associated with the pointer data type. Instead, you identify a pointer variable with the type of data to be stored and an asterisk. 2. Examine the syntax for declaring a pointer variable. Note that an asterisk must precede each pointer variable in a declaration. Teaching Tip Emphasize the various ways pointers can be declared, including the use of white space. Discuss the difference between syntax errors and conventions regarding pointer declarations. Address of Operator (&) 1. Explain the purpose of the address of operator and give an example of its use. Teaching Tip Remind your students that the & symbol has been used in previous chapters to denote a reference parameter. Relate the two by explaining that a reference parameter holds the address of the argument that is passed to the calling function. Dereferencing Operator (*) 1. Explain the purpose of the dereferencing operator and give an example of its use. 2. Illustrate how the address of and dereferencing operators access memory with Figures 13-1 through 13-4. 3. Step through the program in Example 13-1 to demonstrate the use of pointer variables. Teaching Tip Students will likely encounter compiler or execution errors when coding with pointers for the first time. Verify that they understand the use of the address of and dereferencing operator with several examples in class. C++ Programming: Program Design Including Data Structures, Fourth Edition Teaching Tip 13-4 Students will feel more comfortable with pointers as they learn to recognize and debug errors in code with pointer variables. Ask the students to work in small groups and create a small program such as the one in this section. They should then introduce errors and make a note of them. Ask them to present their program in class and see if other students pick up on their errors. At the end of their presentation, they should debug and execute their code. Quick Quiz 1 1. What is the general syntax to declare a pointer variable? Answer: dataType *identifier; 2. The value of a pointer variable is always a(n) ____________________. Answer: memory address 3. True or False: The address of operator is a binary operator. Answer: False 4. True or False: There is no name associated with pointer data types. Answer: True Classes, Structs, and Pointer Variables 1. Explain how to declare pointer variables to classes and structs. 2. Describe the two methods of accessing member variables with pointer variables of a class or struct type. 3. Examine the syntax of both of the above methods. Note the precedence rules of the dereferencing and dot operators. 4. Use Example 13-3 to illustrate how pointers work with member functions. Clarify how memory is accessed with Figures 13-6 and 13-7. Teaching Tip Verify that students understand how to use the member access operator arrow when accessing pointer variables of a class or struct type. Emphasize that this is the most commonly used access technique and discuss the advantages of using this operator rather than the combination of the dot/dereferencing operators. C++ Programming: Program Design Including Data Structures, Fourth Edition 13-5 Initializing Pointer Variables 1. Reiterate that C++ does not initialize variables. 2. Explain that pointer variables are generally initialized with the constant NULL or the integer 0. Teaching Tip Emphasize that the majority of errors your students will encounter when programming with pointers involve the lack of initialization or updating of the pointer value, thereby causing the pointer to point to an unintended location. Teaching Tip Note that although pointer variables point to memory locations, they cannot be used as integer types; the assignment of the number 0 is only allowed because it has the same effect as using the constant NULL. Dynamic Variables 1. Define the term dynamic variable and discuss how pointers are a valuable tool for creating and manipulating data dynamically. 2. Briefly introduce the new and delete operators and explain their purpose. Teaching Tip Reiterate that the programmer is responsible for handling pointer memory and emphasize the importance of allocating and deallocating memory properly. Operator new 1. Describe the two forms of the operator new and examine the syntax for each. 2. Use the code snippets in this section to illustrate how memory is allocated dynamically and then manipulated for primitive types, strings, and arrays. Teaching Tip Illustrate the results of attempting to access pointer memory for a string or array without the new operator. Operator delete 1. Describe a memory leak using Figures 13-8 through 13-11. C++ Programming: Program Design Including Data Structures, Fourth Edition 13-6 2. Explain how to use the operator delete to avoid memory leaks. 3. Examine the syntax of the two forms of the delete operator. 4. Define the term dangling pointer and explain how to avoid this problem. Teaching Tip This section is difficult to grasp, especially the portions involving arrays. Emphasize the two-step process in deallocating memory – deleting the memory and setting the pointer to NULL. Quick Quiz 2 1. What is the purpose of the member access operator arrow? Answer: The member access operator arrow simplifies the accessing of class or struct members with a pointer. 2. Write an equivalent statement to the following: studentPtr.gpa = 3.9;. Answer: (*studentPtr).gpa = 3.9; 3. Variables that are created during program execution are called ____________________ variables. Answer: dynamic 4. True or False: Any integer can be assigned to a pointer variable. Answer: False Operations on Pointer Variables 1. Discuss the operations that are allowed on pointer variables. 2. Illustrate the effect of using assignment and relational operators on pointer variables with the code snippets in this section. 3. Explain how arithmetic operations on pointer variables differ from those on numbers. 4. Demonstrate how the increment and decrement operators are used with pointer variables. Teaching Tip Warn your students about the hazards of using pointer arithmetic and encourage them to be patient when debugging errors involving pointer arithmetic. C++ Programming: Program Design Including Data Structures, Fourth Edition Teaching Tip 13-7 Verify that your students understand how integer types are stored in memory so that they may easily visualize how to add pointer values. Dynamic Arrays 1. Describe the differences between static and dynamic arrays. 2. Discuss situations in which dynamic arrays are preferable to static arrays. 3. Examine the syntax for declaring and initializing a dynamic array. 4. Use Figures 13-12 and 13-13 to describe what takes place in memory when a dynamic array is allocated. 5. Illustrate how a dynamic array is used in a program using Example 13-4. Teaching Tip Explain that dynamic arrays are more flexible than static arrays because the user can define the size of the array at run time. Emphasize, however, that the array must still be initialized with a fixed number of items before it is used. In other words, it is dynamically allocated, but is not a truly dynamic data structure. Review the vector class as an example of a dynamic data structure. Students may get a brief overview of this topic here: http://en.wikipedia.org/wiki/Dynamic_array Functions and Pointers 1. Explain that pointers can be passed by value or by reference. 2. Examine the syntax for passing a pointer as a value parameter and as a reference parameter. Teaching Tip The terminology for using a pointer as a reference parameter in a function header may be a bit baffling to students. Step through a few function headers slowly and remind students of the meaning of the * and & operators. Emphasize why the ordering of the operators is important. Pointers and Function Return Values 1. Explain how to return a pointer from a function. C++ Programming: Program Design Including Data Structures, Fourth Edition 13-8 Dynamic Two-Dimensional Arrays 1. Describe the two techniques presented in this section to declare two-dimensional arrays. 2. Illustrate the use of a two-dimensional array in a program using Example 13-5. Teaching Tip In this section, the two-dimensional array is passed to the fill function both as a value parameter and as a pointer. Does the function change the actual values of the array? Explain that pointers are, in essence, reference types. The implications of this will be clear later on in the chapter. Quick Quiz 3 1. List the operations that can be performed on pointer variables. Answer: Assignment, relational, and the following arithmetic operations: addition, subtraction, increment, and decrement 2. If p is a pointer of type int, what is the result of the statement p++;? Answer: It increments the value of p by four bytes. 3. True or False: The arithmetic operations that are allowed on pointer variables differ from those allowed on numbers. Answer: True 4. To create a dynamic array, you use the second form of the ____________________ operator. Answer: new Shallow versus Deep Copy and Pointers 1. Explain the difference between a shallow and deep copy of a variable. 2. Illustrate the issue involving pointers and a shallow copy of an array with Figures 13-16 through 13-19 and the accompanying code. Explain how creating a deep copy resolves this issue with Figure 13-20 and the accompanying code. Teaching Tip Verify that students understand the code involved in making a deep copy of an array. C++ Programming: Program Design Including Data Structures, Fourth Edition 13-9 Classes and Pointers: Some Peculiarities 1. Examine the class presented in this section using Figure 13-21 and the accompanying code. It will be used to discuss the following sections. Destructor 1. Discuss the purpose of a destructor, particularly as it relates to dynamic memory allocation. 2. Examine the syntax of a destructor function with the example in this section. Teaching Tip Explain that the classes in previous chapters did not need destructors because the programmer did not explicitly allocate memory with the new operator. Assignment Operator 1. Describe the limitations of the built-in assignment operators for classes with pointer variables. Use Figures 13-23 through 13-25 to illustrate how pointer variable class assignments are handled in memory. 2. Note that the use of assignment overloading to avoid shallow copying will be discussed in Chapter 14. Teaching Tip Discuss why it is necessary to extend, or overload, operations for pointer variables. Copy Constructor 1. Describe the purpose of a copy constructor. 2. Explain the C++ default member-wise initialization when an object is initialized with another object (of the same type). Illustrate its limitations using Figures 13-26 through 13-29. 3. Explain how to write a copy constructor function using Example 13-6. Teaching Tip Note that the copy constructor will resolve the parameter problem described in the Teaching Tip of the two-dimensional array discussion. Emphasize again the reality of passing pointer arrays by value; that, in fact, the programmer must ensure that a deep copy is made. C++ Programming: Program Design Including Data Structures, Fourth Edition 13-10 Inheritance, Pointers, and Virtual Functions 1. Emphasize that C++ allows an object of a derived class to be passed to a formal parameter of a base class type. Explain how this might create unintended results with the program in this section. 2. Explain the difference between static and dynamic binding. 3. Describe how C++ provides dynamic binding through the use of virtual functions. 4. Examine the syntax of virtual function prototypes and definitions. 5. Describe how to use virtual functions with value parameters of a class type. Teaching Tip Discuss when it might be useful to pass a derived object to a formal parameter of the base class type; for example, when an array is declared with objects of the base type. Classes and Virtual Destructors 1. Explain when and why the destructor function of a base class should be declared virtual. Abstract Classes and Pure Virtual Functions 1. Define the terms abstract class and pure virtual functions. 2. Describe the situations in which using pure virtual functions and abstract classes is useful. Use the shape class presented in this section as an illustration. 3. Step through the program in Example 13-7 to demonstrate the use of an abstract class. Teaching Tip Explain how a virtual function and a pure virtual function are related, namely, by their run-time binding. Then explain how they are different, namely, in that a pure virtual function is not implemented, but can be used to enforce an implementation in a nonabstract derived class. Teaching Tip Note that an abstract class cannot be instantiated, but that it may contain implementations and values for member functions that are inherited. C++ Programming: Program Design Including Data Structures, Fourth Edition 13-11 Address of Operator and Classes 1. Describe the additional uses of the address of operator in C++. 2. Explain how using the address of operator to manipulate private member variables can be prevented. Use the two versions of the testAdd class presented in this section to illustrate. Quick Quiz 4 1. What is meant by a shallow copy? Answer: In a shallow copy, two pointer variables of the same type point to the same memory. 2. Dynamic memory must be deallocated with the operator ____________________. Answer: delete 3. C++ provides default member-wise initialization of objects that are initialized with the value of an existing object with the ____________________. Answer: copy constructor 4. True or False: In dynamic binding, the necessary code to call a specific function is generated by the compiler. Answer: False Class Discussion Topics 1. The section on classes, structs, and pointers had an example of declaring a variable of a class as a pointer type. What are some reasons to declare classes as pointer variables? 2. Note that the concept of pointers in C++ is inherited from the C language, which relies extensively on the use of pointers. What are the advantages and disadvantages of having the functionality of pointers in a programming language? Do students mind the additional responsibility that comes along with the power of manipulating memory? Are there situations in which manipulating computer memory directly is advantageous? C++ Programming: Program Design Including Data Structures, Fourth Edition 13-12 Additional Projects 1. Rewrite the birthday program you created in Chapter 11 to use a dynamic array of gift objects. Allow the user to determine the maximum number of gifts he or she will add to the list. Include a copy constructor and a destructor in your class. Write a program to test the new implementation of the class. 2. Rewrite the capitals program you created in Chapter 11 to use a dynamic “continent” array that contains countryType classes. You will also create a continentType class that holds this array (if necessary, review the composition of classes from Chapter 12). Allow the user to determine the size of the array. Make the necessary modifications for accessing the countryType objects, and then create a new test program that creates a dynamic array of continentType objects. Additional Resources 1. Pointers: www.cplusplus.com/doc/tutorial/pointers.html 2. C++ Tutorial - About Pointers: http://cplus.about.com/od/learning1/ss/pointers.htm 3. Dynamic Memory Allocation: http://en.wikipedia.org/wiki/Dynamic_memory_allocation 4. Abstract Classes (C++): http://msdn2.microsoft.com/en-us/library/c8whxhf1.aspx Key Terms Abstract class: class that contains one or more pure virtual functions Address of operator (&): unary operator that returns the address of its operand Compile-time binding (static binding): binding in which the necessary code to call a specific function is generated by the compiler Copy constructor: performs the default member-wise initialization provided by the compiler; can be overridden by the programmer to ensure deep copies of a class Dangling pointers: pointer variables that contain the addresses of deallocated memory spaces Deep copy: two or more pointers of the same type that have their own data Dereferencing operator (indirection operator): refers to the object to which its operand (a pointer) points Dynamic array: array created during the execution of a program from a pointer variable and the new operator Dynamic variables: variables that are created during program execution C++ Programming: Program Design Including Data Structures, Fourth Edition 13-13 Member access operator arrow (->): operator -> consists of two consecutive symbols: a hyphen and the greater than symbol; used to simplify the accessing of class components with a pointer Memory leak: when an unused memory space cannot be allocated Null pointer: pointer that has the predefined constant value 0 Pointer variable: variable whose content is a memory address Pure virtual function: functions with no definition Run-time binding (dynamic binding): binding of virtual functions that occurs at program execution time Shallow copy: two or more pointers of the same type point to the same memory; that is, they point to the same data; this occurs when you do not override the default copy constructor for a class containing pointers Virtual destructor: destructor that is marked as virtual in a base class; automatically makes the destructor of a derived class virtual Virtual functions: functions that are dynamically bound, allowing the compiler to generate code that selects the correct function at run time