Presentation is loading. Please wait.

Presentation is loading. Please wait.

Advanced Classes and Dynamic Memory Allocation Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and.

Similar presentations


Presentation on theme: "Advanced Classes and Dynamic Memory Allocation Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and."— Presentation transcript:

1 Advanced Classes and Dynamic Memory Allocation Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and Computer Science University of Wisconsin – Stout Based on the book: Data Structures and Algorithms in C++ (Goodrich, Tamassia, Mount) Some content derived/taken from: http://www.cplusplus.com/ and some from C++ Through Game Programming (Dawson) Connect Speakers for this Presentation

2 Things to Note Homework 4 is Due Soon Homework 5 is Posted on D2L – Do NOT delay in starting it Do not forget to look at the Meta-Info files

3 From Last Time – Reviewed C++ Classes Enumerated Types Operator Overloading – References in C++ – Pointers in C++ Pointers Program: in-class activity Pointers as parameters to functions (Swap) Returning Ptrs from function (on your own - InventoryPtr) Arrays as pointers Tic-Tac-Toe via pointers

4 For Today Some of this has been seen already – We will add a few more details today Advanced Classes – Use friend functions – Overload operators Dynamic Memory – Allocate and free memory – Avoid memory leaks

5 Marker Slide Any General Questions ? Next up – Making friends and overloading functions in your classes (FriendCritter) – Dynamically Allocating Memory – Memory Leaks – Using new and delete [] with arrays – Classes and Dynamic Memory – Allocation Summary – More on Classes Constructors and Destructors with Dynamic Memory Overloading Constructors (copy constructor) Overloading the Assignment Operator Graded In-Class Activity: HeapDataMember

6 Friend Functions and Overloading Operators Friend functions – have complete access to any member data of a class Operator Overloading – allows you to define new meanings – for built-in operators – as they relate to objects of your own class

7 In-Class Activity: FriendCritter Download, compile, and run the FriendCritter example on D2L Discussion on this will follow shortly

8 Looking at FriendCritter //Friend Critter //Demonstrates friend functions and operator overloading #include using namespace std; class Critter { //make the following global functions friends of the Critter class friend void Peek(const Critter& aCritter); friend ostream& operator<<(ostream& os, const Critter& aCritter); public: Critter(const string& name = ""); // default name to empty string private: string m_Name; }; Note the source code here would typically be put into a header file named: FriendCritter.h as it declares the interface to the FriendCritter class

9 Looking at FriendCritter //Friend Critter //Demonstrates friend functions and operator overloading #include using namespace std; class Critter { //make the following global functions friends of the Critter class friend void Peek(const Critter& aCritter); friend ostream& operator<<(ostream& os, const Critter& aCritter); public: Critter(const string& name = ""); // default name to empty string private: string m_Name; }; Peek is identified here as being a global friend function that returns nothing and takes a constant reference to aCritter

10 Looking at FriendCritter //Friend Critter //Demonstrates friend functions and operator overloading #include using namespace std; class Critter { //make the following global functions friends of the Critter class friend void Peek(const Critter& aCritter); friend ostream& operator<<(ostream& os, const Critter& aCritter); public: Critter(const string& name = ""); // default name to empty string private: string m_Name; }; Here the operator<< is being identified as friend of the Critter class Which means we will have to provide a definition of it that can process the Critter class This is called overloading the operator Note the source code here would typically be put into a header file named: FriendCritter.h as it declares the interface to the FriendCritter class

11 Looking at FriendCritter Critter::Critter(const string& name): m_Name(name) { // m_Name = name; // is already done in the line above // via ": m_Name(name)" } //global friend function which can access all of Critter object's members //overloads the << operator so you can send a Critter object to cout ostream& operator<<(ostream& os, const Critter& aCritter) { os << "Critter Object - "; os << "m_Name: " << aCritter.m_Name; return os; } The source code here would typically be put into a definition file named: FriendCritter.cpp The code here defines and IMPLEMENTS the interface to the FriendCritter class

12 Critter::Critter(const string& name): m_Name(name) { // m_Name = name; // is already done in the line above // via ": m_Name(name)" } //global friend function which can access all of Critter object's members //overloads the << operator so you can send a Critter object to cout ostream& operator<<(ostream& os, const Critter& aCritter) { os << "Critter Object - "; os << "m_Name: " << aCritter.m_Name; return os; } Looking at FriendCritter This is a clever way to initialize variables outside the body of the constructor. It comes in useful from time to time.

13 Critter::Critter(const string& name): m_Name(name) { // m_Name = name; // is already done in the line above // via ": m_Name(name)" } //global friend function which can access all of Critter object's members //overloads the << operator so you can send a Critter object to cout ostream& operator<<(ostream& os, const Critter& aCritter) { os << "Critter Object - "; os << "m_Name: " << aCritter.m_Name; return os; } Looking at FriendCritter Here we are “overloading” the operator<< because we are adding to the “load” of types the operator can handle i.e. it now must process data of type: class Critter in addition to all the other types So its potential work “load” has increased

14 Critter::Critter(const string& name): m_Name(name) { // m_Name = name; // is already done in the line above // via ": m_Name(name)" } //global friend function which can access all of Critter object's members //overloads the << operator so you can send a Critter object to cout ostream& operator<<(ostream& os, const Critter& aCritter) { os << "Critter Object - "; os << "m_Name: " << aCritter.m_Name; return os; } Looking at FriendCritter Normally you do NOT want to put additional information into the output generated by operator<< So this line typically would NOT be here - typically only want to output just the member data of the class

15 Critter::Critter(const string& name): m_Name(name) { // m_Name = name; // is already done in the line above // via ": m_Name(name)" } //global friend function which can access all of Critter object's members //overloads the << operator so you can send a Critter object to cout ostream& operator<<(ostream& os, const Critter& aCritter) { os << "Critter Object - "; os << "m_Name: " << aCritter.m_Name; return os; } Looking at FriendCritter Because operator<< is a friend of the FriendCritter class it can use the “dot” notation access member data

16 Looking at FriendCritter void Peek(const Critter& aCritter); int main() { Critter crit("Poochie"); cout << "Calling Peek() to access crit's private data member, m_Name: \n"; Peek(crit); cout << "\nSending crit object to cout with the << operator:\n"; cout << crit; return 0; } //global friend function which can access all of a Critter object's members void Peek(const Critter& aCritter) { cout << aCritter.m_Name << endl; } The source code here would typically be put into whatever file holds the main() function Perhaps named FriendCritterTester.cpp This code usually is where the class is used. The global friend function Peek is also shown here. Functions such as this would more often be found in the file: FriendCritter.cpp file As that would group all functions definitions related to the class FriendCritter in one file It is placed here to show there are options.

17 Looking at FriendCritter void Peek(const Critter& aCritter); int main() { Critter crit("Poochie"); cout << "Calling Peek() to access crit's private data member, m_Name: \n"; Peek(crit); cout << "\nSending crit object to cout with the << operator:\n"; cout << crit; return 0; } // global friend function which can access all of a Critter object's members void Peek(const Critter& aCritter) { cout << aCritter.m_Name << endl; } Declare and Instantiate a Critter named Poochie

18 Looking at FriendCritter void Peek(const Critter& aCritter); int main() { Critter crit("Poochie"); cout << "Calling Peek() to access crit's private data member, m_Name: \n"; Peek(crit); cout << "\nSending crit object to cout with the << operator:\n"; cout << crit; return 0; } // global friend function which can access all of a Critter object's members void Peek(const Critter& aCritter) { cout << aCritter.m_Name << endl; } Call the global function Peek

19 Looking at FriendCritter void Peek(const Critter& aCritter); int main() { Critter crit("Poochie"); cout << "Calling Peek() to access crit's private data member, m_Name: \n"; Peek(crit); cout << "\nSending crit object to cout with the << operator:\n"; cout << crit; return 0; } // global friend function which can access all of a Critter object's members void Peek(const Critter& aCritter) { cout << aCritter.m_Name << endl; } Make use of the overloaded operator<<

20 Looking at FriendCritter void Peek(const Critter& aCritter); int main() { Critter crit("Poochie"); cout << "Calling Peek() to access crit's private data member, m_Name: \n"; Peek(crit); cout << "\nSending crit object to cout with the << operator:\n"; cout << crit; return 0; } // global friend function which can access all of a Critter object's members void Peek(const Critter& aCritter) { cout << aCritter.m_Name << endl; } Because Peek is a friend of FriendCritter it can access member data of the class via the “dot” notation

21 Marker Slide Any Questions on: – Making friends and overloading functions in your classes (FriendCritter) Next up – Dynamically Allocating Memory – Memory Leaks – Using new and delete [] with arrays – Classes and Dynamic Memory – Allocation Summary – More on Classes Constructors and Destructors with Dynamic Memory Overloading Constructors (copy constructor) Overloading the Assignment Operator Graded In-Class Activity: HeapDataMember

22 Memory Allocation Most variables you use have their memory “pre-allocated” – Well before the program is run – And each variable takes up the same space every run – This defines static memory allocation – These variables are allocated on “the stack”

23 Why dynamically allocate? Efficiency. – You use only the amount of memory you need at any time – You need 100 enemies at the beginning of the level? Allocate them when the level loads Deallocate when the level completes No need to keep them around for the whole game – Extra bonus You can create an object in one function that you can access after that function ends

24 Dynamic Memory Allocation What to know – Use new to allocate Allocates memory on the Heap (aka Free Store) – Use delete or delete [] to de-allocate – For arrays keep track of how much you allocate You will have a variable pointing at the first array element – int *myArray = new int[10]; You will need to know where the array ends – myArray[0] is the first element – myArray[9] is the last (0, 1, 2, …9  ten elements)

25 Using new for Variable Allocation Example (for illustration of new w.r.t. dynamic arrays) int main() { char *strPtr = NULL; // a pointer to a string, init to point at NULL string inputStr; // an std::string for keyboard input // get a string from the keyboard cout << “Please enter a word and press enter” << endl; cin >> inputStr; // Want to copy inputStr into strPtr, Alloc memory first strPtr = new char[ inputStr.length() + 1]; // +1 for the ‘\0’ at end // Use a for loop to copy it for (int i=0; i < inputStr.length(); i++) strPtr[i] = inputStr.at(i); strPtr[ inputStr.length() ] = ‘\0’; // null terminate the char string delete [] strPtr; // Free the memory we allocated return 0; // 0 for success (some progs return EXIT_SUCCESS) }

26 The Heap Program The program you are about to look at – Dynamically allocates memory on the heap (free store) for an integer value assigns it a value displays it – Then calls a function which also dynamically allocates memory for an integer variable assigns it a value returns a pointer to it – The main function then uses the pointer to display the second value – Memory for both variables is then deallocated and the program ends

27 Class Activity: Heap Program Enter and run the following program // Heap // Demonstrates dynamically allocating memory #include using namespace std; int* intOnHeap(); //returns an int on the heap int main() { int* pHeap = new int; *pHeap = 10; cout << "*pHeap: " << *pHeap << "\n\n"; int* pHeap2 = intOnHeap(); cout << "*pHeap2: " << *pHeap2 << "\n\n"; cout << "Freeing memory pointed to by pHeap.\n\n"; delete pHeap; cout << "Freeing memory pointed to by pHeap2.\n\n"; delete pHeap2; // get rid of dangling pointers pHeap = 0; pHeap2 = 0; return 0; } int* intOnHeap() { int* pTemp = new int(20); return pTemp; }

28 Examination of: Heap Program // Heap // Demonstrates dynamically allocating memory #include using namespace std; int* intOnHeap(); //returns an int on the heap int main() { int* pHeap = new int; *pHeap = 10; cout << "*pHeap: " << *pHeap << "\n\n"; int* pHeap2 = intOnHeap(); cout << "*pHeap2: " << *pHeap2 << "\n\n"; cout << "Freeing memory pointed to by pHeap.\n\n"; delete pHeap; cout << "Freeing memory pointed to by pHeap2.\n\n"; delete pHeap2; // get rid of dangling pointers pHeap = 0; pHeap2 = 0; return 0; } int* intOnHeap() { int* pTemp = new int(20); return pTemp; } int* intOnHeap() This declares a function that will return an integer pointer Presumably to an integer allocated on the heap (free store)

29 Examination of: Heap Program // Heap // Demonstrates dynamically allocating memory #include using namespace std; int* intOnHeap(); //returns an int on the heap int main() { int* pHeap = new int; *pHeap = 10; cout << "*pHeap: " << *pHeap << "\n\n"; int* pHeap2 = intOnHeap(); cout << "*pHeap2: " << *pHeap2 << "\n\n"; cout << "Freeing memory pointed to by pHeap.\n\n"; delete pHeap; cout << "Freeing memory pointed to by pHeap2.\n\n"; delete pHeap2; // get rid of dangling pointers pHeap = 0; pHeap2 = 0; return 0; } int* intOnHeap() { int* pTemp = new int(20); return pTemp; } Declare an integer pointer variable name pHeap

30 Examination of: Heap Program // Heap // Demonstrates dynamically allocating memory #include using namespace std; int* intOnHeap(); //returns an int on the heap int main() { int* pHeap = new int; *pHeap = 10; cout << "*pHeap: " << *pHeap << "\n\n"; int* pHeap2 = intOnHeap(); cout << "*pHeap2: " << *pHeap2 << "\n\n"; cout << "Freeing memory pointed to by pHeap.\n\n"; delete pHeap; cout << "Freeing memory pointed to by pHeap2.\n\n"; delete pHeap2; // get rid of dangling pointers pHeap = 0; pHeap2 = 0; return 0; } int* intOnHeap() { int* pTemp = new int(20); return pTemp; } Declare an integer pointer variable name pHeap Initialize it to point to a NEWLY allocated integer (memory allocated on the free store – aka heap)

31 Examination of: Heap Program // Heap // Demonstrates dynamically allocating memory #include using namespace std; int* intOnHeap(); //returns an int on the heap int main() { int* pHeap = new int; *pHeap = 10; cout << "*pHeap: " << *pHeap << "\n\n"; int* pHeap2 = intOnHeap(); cout << "*pHeap2: " << *pHeap2 << "\n\n"; cout << "Freeing memory pointed to by pHeap.\n\n"; delete pHeap; cout << "Freeing memory pointed to by pHeap2.\n\n"; delete pHeap2; // get rid of dangling pointers pHeap = 0; pHeap2 = 0; return 0; } int* intOnHeap() { int* pTemp = new int(20); return pTemp; } Use the “star” to dereference the pointer and assign what it points to the value 10 *pHeap = 10;

32 Examination of: Heap Program // Heap // Demonstrates dynamically allocating memory #include using namespace std; int* intOnHeap(); //returns an int on the heap int main() { int* pHeap = new int; *pHeap = 10; cout << "*pHeap: " << *pHeap << "\n\n"; int* pHeap2 = intOnHeap(); cout << "*pHeap2: " << *pHeap2 << "\n\n"; cout << "Freeing memory pointed to by pHeap.\n\n"; delete pHeap; cout << "Freeing memory pointed to by pHeap2.\n\n"; delete pHeap2; // get rid of dangling pointers pHeap = 0; pHeap2 = 0; return 0; } int* intOnHeap() { int* pTemp = new int(20); return pTemp; } Again Use the “star” to dereference the pointer This time to output the value of what it points to

33 Examination of: Heap Program // Heap // Demonstrates dynamically allocating memory #include using namespace std; int* intOnHeap(); //returns an int on the heap int main() { int* pHeap = new int; *pHeap = 10; cout << "*pHeap: " << *pHeap << "\n\n"; int* pHeap2 = intOnHeap(); cout << "*pHeap2: " << *pHeap2 << "\n\n"; cout << "Freeing memory pointed to by pHeap.\n\n"; delete pHeap; cout << "Freeing memory pointed to by pHeap2.\n\n"; delete pHeap2; // get rid of dangling pointers pHeap = 0; pHeap2 = 0; return 0; } int* intOnHeap() { int* pTemp = new int(20); return pTemp; } Declare another integer pointer variable, this one is name pHeap2

34 Examination of: Heap Program // Heap // Demonstrates dynamically allocating memory #include using namespace std; int* intOnHeap(); //returns an int on the heap int main() { int* pHeap = new int; *pHeap = 10; cout << "*pHeap: " << *pHeap << "\n\n"; int* pHeap2 = intOnHeap(); cout << "*pHeap2: " << *pHeap2 << "\n\n"; cout << "Freeing memory pointed to by pHeap.\n\n"; delete pHeap; cout << "Freeing memory pointed to by pHeap2.\n\n"; delete pHeap2; // get rid of dangling pointers pHeap = 0; pHeap2 = 0; return 0; } int* intOnHeap() { int* pTemp = new int(20); return pTemp; } Declare another integer pointer variable, this one is name pHeap2 Initialize it to have the pointer returned from intOnHeap()

35 Examination of: Heap Program // Heap // Demonstrates dynamically allocating memory #include using namespace std; int* intOnHeap(); //returns an int on the heap int main() { int* pHeap = new int; *pHeap = 10; cout << "*pHeap: " << *pHeap << "\n\n"; int* pHeap2 = intOnHeap(); cout << "*pHeap2: " << *pHeap2 << "\n\n"; cout << "Freeing memory pointed to by pHeap.\n\n"; delete pHeap; cout << "Freeing memory pointed to by pHeap2.\n\n"; delete pHeap2; // get rid of dangling pointers pHeap = 0; pHeap2 = 0; return 0; } int* intOnHeap() { int* pTemp = new int(20); return pTemp; } Free the memory of both pointer variables using delete

36 Examination of: Heap Program // Heap // Demonstrates dynamically allocating memory #include using namespace std; int* intOnHeap(); //returns an int on the heap int main() { int* pHeap = new int; *pHeap = 10; cout << "*pHeap: " << *pHeap << "\n\n"; int* pHeap2 = intOnHeap(); cout << "*pHeap2: " << *pHeap2 << "\n\n"; cout << "Freeing memory pointed to by pHeap.\n\n"; delete pHeap; cout << "Freeing memory pointed to by pHeap2.\n\n"; delete pHeap2; // get rid of dangling pointers pHeap = 0; pHeap2 = 0; return 0; } int* intOnHeap() { int* pTemp = new int(20); return pTemp; } For safety set both pointers to point to NULL (aka zero)

37 Examination of: Heap Program // Heap // Demonstrates dynamically allocating memory #include using namespace std; int* intOnHeap(); //returns an int on the heap int main() { int* pHeap = new int; *pHeap = 10; cout << "*pHeap: " << *pHeap << "\n\n"; int* pHeap2 = intOnHeap(); cout << "*pHeap2: " << *pHeap2 << "\n\n"; cout << "Freeing memory pointed to by pHeap.\n\n"; delete pHeap; cout << "Freeing memory pointed to by pHeap2.\n\n"; delete pHeap2; // get rid of dangling pointers pHeap = 0; pHeap2 = 0; return 0; } int* intOnHeap() { int* pTemp = new int(20); return pTemp; } Declare an integer pointer named pTemp

38 Examination of: Heap Program // Heap // Demonstrates dynamically allocating memory #include using namespace std; int* intOnHeap(); //returns an int on the heap int main() { int* pHeap = new int; *pHeap = 10; cout << "*pHeap: " << *pHeap << "\n\n"; int* pHeap2 = intOnHeap(); cout << "*pHeap2: " << *pHeap2 << "\n\n"; cout << "Freeing memory pointed to by pHeap.\n\n"; delete pHeap; cout << "Freeing memory pointed to by pHeap2.\n\n"; delete pHeap2; // get rid of dangling pointers pHeap = 0; pHeap2 = 0; return 0; } int* intOnHeap() { int* pTemp = new int(20); return pTemp; } Declare an integer pointer named pTemp Initialize it to point to newly allocated memory holding the value 20

39 Examination of: Heap Program // Heap // Demonstrates dynamically allocating memory #include using namespace std; int* intOnHeap(); //returns an int on the heap int main() { int* pHeap = new int; *pHeap = 10; cout << "*pHeap: " << *pHeap << "\n\n"; int* pHeap2 = intOnHeap(); cout << "*pHeap2: " << *pHeap2 << "\n\n"; cout << "Freeing memory pointed to by pHeap.\n\n"; delete pHeap; cout << "Freeing memory pointed to by pHeap2.\n\n"; delete pHeap2; // get rid of dangling pointers pHeap = 0; pHeap2 = 0; return 0; } int* intOnHeap() { int* pTemp = new int(20); return pTemp; } Declare an integer pointer named pTemp Initialize it to point to newly allocated memory holding the value 20 CAUTION If those parentheses get changed into square brackets [20] something entirely different happens!

40 Examination of: Heap Program // Heap // Demonstrates dynamically allocating memory #include using namespace std; int* intOnHeap(); //returns an int on the heap int main() { int* pHeap = new int; *pHeap = 10; cout << "*pHeap: " << *pHeap << "\n\n"; int* pHeap2 = intOnHeap(); cout << "*pHeap2: " << *pHeap2 << "\n\n"; cout << "Freeing memory pointed to by pHeap.\n\n"; delete pHeap; cout << "Freeing memory pointed to by pHeap2.\n\n"; delete pHeap2; // get rid of dangling pointers pHeap = 0; pHeap2 = 0; return 0; } int* intOnHeap() { int* pTemp = new int(20); return pTemp; } Declare an integer pointer named pTemp Initialize it to point to newly allocated memory holding the value 20 CAUTION If those parentheses get changed into square brackets [20] something entirely different happens! new int[20];  allocates an array of 20 integers

41 Examination of: Heap Program // Heap // Demonstrates dynamically allocating memory #include using namespace std; int* intOnHeap(); //returns an int on the heap int main() { int* pHeap = new int; *pHeap = 10; cout << "*pHeap: " << *pHeap << "\n\n"; int* pHeap2 = intOnHeap(); cout << "*pHeap2: " << *pHeap2 << "\n\n"; cout << "Freeing memory pointed to by pHeap.\n\n"; delete pHeap; cout << "Freeing memory pointed to by pHeap2.\n\n"; delete pHeap2; // get rid of dangling pointers pHeap = 0; pHeap2 = 0; return 0; } int* intOnHeap() { int* pTemp = new int(20); return pTemp; } Declare an integer pointer named pTemp Initialize it to point to newly allocated memory holding the value 20 Parentheses are okay new int(20) allocates ONE integer with value 20

42 Marker Slide Any Questions on: – Making friends and overloading functions in your classes (FriendCritter) – Dynamically Allocating Memory Next up – Memory Leaks – Using new and delete [] with arrays – Classes and Dynamic Memory – Allocation Summary – More on Classes Constructors and Destructors with Dynamic Memory Overloading Constructors (copy constructor) Overloading the Assignment Operator Graded In-Class Activity: HeapDataMember

43 Memory Leaks Having the power to allocate memory – Means you – Have the responsibility to de-allocate it – Failure to de-allocate memory causes memory leaks And Bad things happen You wouldn’t want bad things to happen – Would you?

44 Memory Leaks Having the power to allocate memory – Means you – Have the responsibility to de-allocate it – Failure to de-allocate memory causes memory leaks And Bad things happen You wouldn’t want bad things to happen – Would you?

45 Example Leak Adding and calling the below function to the Heap program just discussed would cause a memory leak – So do NOT do this void leak1() { int* drip1 = new int(30); } Allocates memory Function ends Pointer to the allocated memory is gone But the allocated memory remains With no way to deallocate it BAD, VERY BAD

46 Example Leak Adding and calling the below function to the Heap program just discussed would cause a memory leak – So do NOT do this void leak2() { int* drip2 = new int(50); drip2 = new int(100); delete drip2; } Allocates memory and assigns to a pointer – OK Allocates more memory, assigns to same pointer but does NOT free the first memory allocated BAD VERY BAD Does deallocate the second allocation, so that’s good But the first allocation again now no way to free that memory

47 Other Leaks There are MANY, MANY ways to cause memory leaks One rule can prevent them all – Every time there is a new There must be a delete Follow that rule and it will prevent many bad things

48 Marker Slide Any Questions on: – Making friends and overloading functions in your classes (FriendCritter) – Dynamically Allocating Memory – Memory Leaks Next up – Using new and delete [] with arrays – Classes and Dynamic Memory – Allocation Summary – More on Classes Constructors and Destructors with Dynamic Memory Overloading Constructors (copy constructor) Overloading the Assignment Operator Graded In-Class Activity: HeapDataMember

49 Arrays: new and delete [] To dynamically allocate an array you need to use square brackets in both the new line and the delete line The rule: – If you see a line with new and square brackets – Then the delete that goes with it must have square brackets too Examples follow on next slide

50 Example: Arrays and Dynamic Memory int main() { int *pIntArray = new int[45]; delete [] pIntArray; someClass *pSC = new someClass[23]; delete [] pSC; }

51 Another Example: Arrays and Dynamic Memory #include using namespace std; int main () { int i,n; int * p; cout << "How many numbers would you like to type? "; cin >> i; p= new (nothrow) int[i]; if (p == 0) cout << "Error: memory could not be allocated"; else { for (n=0; n<i; n++) { cout << "Enter number: "; cin >> p[n]; } cout << "You have entered: "; for (n=0; n<i; n++) cout << p[n] << ", "; delete[] p; } return 0; } How many numbers would you like to type? 5 Enter number : 75 Enter number : 436 Enter number : 1067 Enter number : 8 Enter number : 32 You have entered: 75, 436, 1067, 8, 32,

52 Another Example: Arrays and Dynamic Memory #include using namespace std; int main () { int i,n; int * p; cout << "How many numbers would you like to type? "; cin >> i; p= new (nothrow) int[i]; if (p == 0) cout << "Error: memory could not be allocated"; else { for (n=0; n<i; n++) { cout << "Enter number: "; cin >> p[n]; } cout << "You have entered: "; for (n=0; n<i; n++) cout << p[n] << ", "; delete[] p; } return 0; } Declare an integer pointer p

53 Another Example: Arrays and Dynamic Memory #include using namespace std; int main () { int i,n; int * p; cout << "How many numbers would you like to type? "; cin >> i; p= new (nothrow) int[i]; if (p == 0) cout << "Error: memory could not be allocated"; else { for (n=0; n<i; n++) { cout << "Enter number: "; cin >> p[n]; } cout << "You have entered: "; for (n=0; n<i; n++) cout << p[n] << ", "; delete[] p; } return 0; } How many numbers would you like to type? 5 Ask the user for the size of the array to allocate

54 Another Example: Arrays and Dynamic Memory #include using namespace std; int main () { int i,n; int * p; cout << "How many numbers would you like to type? "; cin >> i; p= new (nothrow) int[i]; if (p == 0) cout << "Error: memory could not be allocated"; else { for (n=0; n<i; n++) { cout << "Enter number: "; cin >> p[n]; } cout << "You have entered: "; for (n=0; n<i; n++) cout << p[n] << ", "; delete[] p; } return 0; } How many numbers would you like to type? 5 Allocate the requested memory and assign the pointer new returns to the variable named p the “(nothrow)” is a parameter to new It is not required and may or may not be supported by your compiler

55 Another Example: Arrays and Dynamic Memory #include using namespace std; int main () { int i,n; int * p; cout << "How many numbers would you like to type? "; cin >> i; p= new (nothrow) int[i]; if (p == 0) cout << "Error: memory could not be allocated"; else { for (n=0; n<i; n++) { cout << "Enter number: "; cin >> p[n]; } cout << "You have entered: "; for (n=0; n<i; n++) cout << p[n] << ", "; delete[] p; } return 0; } How many numbers would you like to type? 5 If new returns zero (the null pointer) it was unable to allocate the requested memory

56 Another Example: Arrays and Dynamic Memory #include using namespace std; int main () { int i,n; int * p; cout << "How many numbers would you like to type? "; cin >> i; p= new (nothrow) int[i]; if (p == 0) cout << "Error: memory could not be allocated"; else { for (n=0; n<i; n++) { cout << "Enter number: "; cin >> p[n]; } cout << "You have entered: "; for (n=0; n<i; n++) cout << p[n] << ", "; delete[] p; } return 0; } How many numbers would you like to type? 5 Enter number : 75 Enter number : 436 Enter number : 1067 Enter number : 8 Enter number : 32 Standard for-loop Notice the square brackets access element n of the array referenced by p. So p is acting as an array name.

57 Another Example: Arrays and Dynamic Memory #include using namespace std; int main () { int i,n; int * p; cout << "How many numbers would you like to type? "; cin >> i; p= new (nothrow) int[i]; if (p == 0) cout << "Error: memory could not be allocated"; else { for (n=0; n<i; n++) { cout << "Enter number: "; cin >> p[n]; } cout << "You have entered: "; for (n=0; n<i; n++) cout << p[n] << ", "; delete[] p; } return 0; } How many numbers would you like to type? 5 Enter number : 75 Enter number : 436 Enter number : 1067 Enter number : 8 Enter number : 32 You have entered: 75, Another standard for-loop outputting the numbers entered

58 Another Example: Arrays and Dynamic Memory #include using namespace std; int main () { int i,n; int * p; cout << "How many numbers would you like to type? "; cin >> i; p= new (nothrow) int[i]; if (p == 0) cout << "Error: memory could not be allocated"; else { for (n=0; n<i; n++) { cout << "Enter number: "; cin >> p[n]; } cout << "You have entered: "; for (n=0; n<i; n++) cout << p[n] << ", "; delete[] p; } return 0; } How many numbers would you like to type? 5 Enter number : 75 Enter number : 436 Enter number : 1067 Enter number : 8 Enter number : 32 You have entered: 75, 436, Another standard for-loop outputting the numbers entered

59 Another Example: Arrays and Dynamic Memory #include using namespace std; int main () { int i,n; int * p; cout << "How many numbers would you like to type? "; cin >> i; p= new (nothrow) int[i]; if (p == 0) cout << "Error: memory could not be allocated"; else { for (n=0; n<i; n++) { cout << "Enter number: "; cin >> p[n]; } cout << "You have entered: "; for (n=0; n<i; n++) cout << p[n] << ", "; delete[] p; } return 0; } How many numbers would you like to type? 5 Enter number : 75 Enter number : 436 Enter number : 1067 Enter number : 8 Enter number : 32 You have entered: 75, 436, 1067, Another standard for-loop outputting the numbers entered

60 Another Example: Arrays and Dynamic Memory #include using namespace std; int main () { int i,n; int * p; cout << "How many numbers would you like to type? "; cin >> i; p= new (nothrow) int[i]; if (p == 0) cout << "Error: memory could not be allocated"; else { for (n=0; n<i; n++) { cout << "Enter number: "; cin >> p[n]; } cout << "You have entered: "; for (n=0; n<i; n++) cout << p[n] << ", "; delete[] p; } return 0; } How many numbers would you like to type? 5 Enter number : 75 Enter number : 436 Enter number : 1067 Enter number : 8 Enter number : 32 You have entered: 75, 436, 1067, 8, Another standard for-loop outputting the numbers entered

61 Another Example: Arrays and Dynamic Memory #include using namespace std; int main () { int i,n; int * p; cout << "How many numbers would you like to type? "; cin >> i; p= new (nothrow) int[i]; if (p == 0) cout << "Error: memory could not be allocated"; else { for (n=0; n<i; n++) { cout << "Enter number: "; cin >> p[n]; } cout << "You have entered: "; for (n=0; n<i; n++) cout << p[n] << ", "; delete[] p; } return 0; } How many numbers would you like to type? 5 Enter number : 75 Enter number : 436 Enter number : 1067 Enter number : 8 Enter number : 32 You have entered: 75, 436, 1067, 8, 32, Another standard for-loop outputting the numbers entered

62 Another Example: Arrays and Dynamic Memory #include using namespace std; int main () { int i,n; int * p; cout << "How many numbers would you like to type? "; cin >> i; p= new (nothrow) int[i]; if (p == 0) cout << "Error: memory could not be allocated"; else { for (n=0; n<i; n++) { cout << "Enter number: "; cin >> p[n]; } cout << "You have entered: "; for (n=0; n<i; n++) cout << p[n] << ", "; delete[] p; } return 0; } How many numbers would you like to type? 5 Enter number : 75 Enter number : 436 Enter number : 1067 Enter number : 8 Enter number : 32 You have entered: 75, 436, 1067, 8, 32, Use delete [] to de-allocate the array referenced by p

63 Marker Slide Any Questions on: – Making friends and overloading functions in your classes (FriendCritter) – Dynamically Allocating Memory – Memory Leaks – Using new and delete [] with arrays Next up – Classes and Dynamic Memory – Allocation Summary – More on Classes Constructors and Destructors with Dynamic Memory Overloading Constructors (copy constructor) Overloading the Assignment Operator Graded In-Class Activity: HeapDataMember

64 Classes and Dynamic Memory // pointer to classes example #include using namespace std; class CRectangle { int width, height; public: void set_values (int, int); int area (void) {return (width * height);} }; void CRectangle::set_values (int a, int b) { width = a; height = b; } int main () { CRectangle a, *b, *c; CRectangle * d = new CRectangle[2]; b= new CRectangle; c= &a; a.set_values (1,2); b->set_values (3,4); d->set_values (5,6); d[1].set_values (7,8); a area: 2 *b area: 12 *c area: 2 d[0] area: 30 d[1] area: 56 Main points: [go to next slide] cout << "a area: " << a.area() << endl; cout area() << endl; cout << "d[0] area: " << d[0].area() << endl; cout << "d[1] area: " << d[1].area() << endl; delete[] d; delete b; return 0; }

65 Classes and Dynamic Memory // pointer to classes example #include using namespace std; class CRectangle { int width, height; public: void set_values (int, int); int area (void) {return (width * height);} }; void CRectangle::set_values (int a, int b) { width = a; height = b; } int main () { CRectangle a, *b, *c; CRectangle * d = new CRectangle[2]; b= new CRectangle; c= &a; a.set_values (1,2); b->set_values (3,4); d->set_values (5,6); d[1].set_values (7,8); a area: 2 *b area: 12 *c area: 2 d[0] area: 30 d[1] area: 56 Main points: You can have pointers to classes too cout << "a area: " << a.area() << endl; cout area() << endl; cout << "d[0] area: " << d[0].area() << endl; cout << "d[1] area: " << d[1].area() << endl; delete[] d; delete b; return 0; }

66 Classes and Dynamic Memory // pointer to classes example #include using namespace std; class CRectangle { int width, height; public: void set_values (int, int); int area (void) {return (width * height);} }; void CRectangle::set_values (int a, int b) { width = a; height = b; } int main () { CRectangle a, *b, *c; CRectangle * d = new CRectangle[2]; b= new CRectangle; c= &a; a.set_values (1,2); b->set_values (3,4); d->set_values (5,6); d[1].set_values (7,8); a area: 2 *b area: 12 *c area: 2 d[0] area: 30 d[1] area: 56 Main points: You can have pointers to classes too The can point to dynamically allocated arrays cout << "a area: " << a.area() << endl; cout area() << endl; cout << "d[0] area: " << d[0].area() << endl; cout << "d[1] area: " << d[1].area() << endl; delete[] d; delete b; return 0; }

67 Classes and Dynamic Memory // pointer to classes example #include using namespace std; class CRectangle { int width, height; public: void set_values (int, int); int area (void) {return (width * height);} }; void CRectangle::set_values (int a, int b) { width = a; height = b; } int main () { CRectangle a, *b, *c; CRectangle * d = new CRectangle[2]; b= new CRectangle; c= &a; a.set_values (1,2); b->set_values (3,4); d->set_values (5,6); d[1].set_values (7,8); a area: 2 *b area: 12 *c area: 2 d[0] area: 30 d[1] area: 56 Main points: You can have pointers to classes too The can point to dynamically allocated arrays or dynamically allocated single entities cout << "a area: " << a.area() << endl; cout area() << endl; cout << "d[0] area: " << d[0].area() << endl; cout << "d[1] area: " << d[1].area() << endl; delete[] d; delete b; return 0; }

68 Classes and Dynamic Memory // pointer to classes example #include using namespace std; class CRectangle { int width, height; public: void set_values (int, int); int area (void) {return (width * height);} }; void CRectangle::set_values (int a, int b) { width = a; height = b; } int main () { CRectangle a, *b, *c; CRectangle * d = new CRectangle[2]; b= new CRectangle; c= &a; a.set_values (1,2); b->set_values (3,4); d->set_values (5,6); d[1].set_values (7,8); a area: 2 *b area: 12 *c area: 2 d[0] area: 30 d[1] area: 56 Main points: You can have pointers to classes too The can point to dynamically allocated arrays or dynamically allocated single entities or ‘normal’ allocated entities cout << "a area: " << a.area() << endl; cout area() << endl; cout << "d[0] area: " << d[0].area() << endl; cout << "d[1] area: " << d[1].area() << endl; delete[] d; delete b; return 0; }

69 Classes and Dynamic Memory // pointer to classes example #include using namespace std; class CRectangle { int width, height; public: void set_values (int, int); int area (void) {return (width * height);} }; void CRectangle::set_values (int a, int b) { width = a; height = b; } int main () { CRectangle a, *b, *c; CRectangle * d = new CRectangle[2]; b= new CRectangle; c= &a; a.set_values (1,2); b->set_values (3,4); d->set_values (5,6); d[1].set_values (7,8); a area: 2 *b area: 12 *c area: 2 d[0] area: 30 d[1] area: 56 Main points: You can have pointers to classes too The can point to dynamically allocated arrays or dynamically allocated single entities or ‘normal’ allocated entities Dynamically Alloc’d arrays use delete [] cout << "a area: " << a.area() << endl; cout area() << endl; cout << "d[0] area: " << d[0].area() << endl; cout << "d[1] area: " << d[1].area() << endl; delete[] d; delete b; return 0; }

70 Classes and Dynamic Memory // pointer to classes example #include using namespace std; class CRectangle { int width, height; public: void set_values (int, int); int area (void) {return (width * height);} }; void CRectangle::set_values (int a, int b) { width = a; height = b; } int main () { CRectangle a, *b, *c; CRectangle * d = new CRectangle[2]; b= new CRectangle; c= &a; a.set_values (1,2); b->set_values (3,4); d->set_values (5,6); d[1].set_values (7,8); a area: 2 *b area: 12 *c area: 2 d[0] area: 30 d[1] area: 56 Main points: You can have pointers to classes too The can point to dynamically allocated arrays or dynamically allocated single entities or ‘normal’ allocated entities Dynamically Alloc’d arrays use delete [] Dynamically Alloc’d single entities use delete cout << "a area: " << a.area() << endl; cout area() << endl; cout << "d[0] area: " << d[0].area() << endl; cout << "d[1] area: " << d[1].area() << endl; delete[] d; delete b; return 0; }

71 Marker Slide Any Questions on: – Making friends and overloading functions in your classes (FriendCritter) – Dynamically Allocating Memory – Memory Leaks – Using new and delete [] with arrays – Classes and Dynamic Memory Next up – Allocation Summary – More on Classes Constructors and Destructors with Dynamic Memory Overloading Constructors (copy constructor) Overloading the Assignment Operator Graded In-Class Activity: HeapDataMember

72 Free Store Allocation Summary Allocate using new – New allocates an object on the free store, sometimes initializes it, and returns a pointer to it int* pi = new int; – // default initialization (none for int) char* pc = new char('a'); – // explicit initialization double* pd = new double[10]; – // allocation of (uninitialized) array – New throws a bad_alloc exception if it can't allocate

73 Free Store DE-Allocation Summary Deallocate using delete and delete[ ] – delete and delete[ ] return the memory of an object allocated by new to the free store so that the free store can use it for new allocations delete pi;// deallocate an individual object delete pc;// deallocate an individual object delete[ ] pd;// deallocate an array – Delete of a zero-valued pointer ("the null pointer") does nothing char* p = 0; or char *p = NULL; delete p;// harmless

74 Classes and New and Delete You can have pointers to classes – and use new and delete with them – just as with any other type New and Delete inside Classes – Classes typically allocate memory for member variables in the class’s constructor for use while the instantiated object of the class exists – When the object goes out of scope, or is explicitly deleted itself The class’s destructor deallocates the memory that was allocated in the constructor using delete – More on this shortly

75 Marker Slide Any Questions on: – Making friends and overloading functions in your classes (FriendCritter) – Dynamically Allocating Memory – Memory Leaks – Using new and delete [] with arrays – Classes and Dynamic Memory – Allocation Summary Next up – More on Classes Constructors and Destructors with Dynamic Memory Overloading Constructors (copy constructor) Overloading the Assignment Operator Graded In-Class Activity: HeapDataMember

76 More Fun with Classes There still remain several things to be discovered about classes, such as – destructors – copy constructors – overloaded assignment operator= We will do a little review of things you have already seen – establish context – and move into more new stuff

77 A Basic Class: A Place to Start // example: one class, two objects #include using namespace std; class CRectangle { int x, y; // default to private public: void set_values (int,int); int area () {return (x*y);} }; void CRectangle::set_values (int a, int b) { x = a; y = b; } int main () { CRectangle rect, rectb; rect.set_values (3,4); rectb.set_values (5,6); cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0; } rect area: 12 rectb area: 30 Main point: No Constructor, No Destructor Forces call to set_values to initialize stuff No fancy slides setup for this one Does show some change-up options in how you write/format things

78 Constructor // example: class constructor #include using namespace std; class CRectangle { int width, height; public: CRectangle (int,int); int area () {return (width*height);} }; CRectangle::CRectangle (int a, int b) { width = a; height = b; } int main () { CRectangle rect (3,4); CRectangle rectb (5,6); cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0; } rect area: 12 rectb area: 30 Main point: Have a Constructor Stuff gets “auto” initialized

79 Constructor // example: class constructor #include using namespace std; class CRectangle { int width, height; public: CRectangle (int,int); int area () {return (width*height);} }; CRectangle::CRectangle (int a, int b) { width = a; height = b; } int main () { CRectangle rect (3,4); CRectangle rectb (5,6); cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0; } rect area: 12 rectb area: 30 Main point: Have a Constructor Stuff gets “auto” initialized

80 Constructor AND Destructor with Dynamic Memory Allocation // example on constructors and destructors #include using namespace std; class CRectangle { int *width, *height; public: CRectangle (int,int); ~CRectangle (); int area () {return (*width * *height);} }; CRectangle::CRectangle (int a, int b) { width = new int; height = new int; *width = a; *height = b; } CRectangle::~CRectangle () { delete width; delete height; } int main () { CRectangle rect (3,4), rectb (5,6); cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0; } rect area: 12 rectb area: 30 Main points:

81 Constructor AND Destructor with Dynamic Memory Allocation // example on constructors and destructors #include using namespace std; class CRectangle { int *width, *height; public: CRectangle (int,int); ~CRectangle (); int area () {return (*width * *height);} }; CRectangle::CRectangle (int a, int b) { width = new int; height = new int; *width = a; *height = b; } CRectangle::~CRectangle () { delete width; delete height; } int main () { CRectangle rect (3,4), rectb (5,6); cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0; } rect area: 12 rectb area: 30 Main points: Have a Constructor that dynamically allocates some memory and initializes the member vars’ values

82 Constructor AND Destructor with Dynamic Memory Allocation // example on constructors and destructors #include using namespace std; class CRectangle { int *width, *height; public: CRectangle (int,int); ~CRectangle (); int area () {return (*width * *height);} }; CRectangle::CRectangle (int a, int b) { width = new int; height = new int; *width = a; *height = b; } CRectangle::~CRectangle () { delete width; delete height; } int main () { CRectangle rect (3,4), rectb (5,6); cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0; } rect area: 12 rectb area: 30 Main points: Have a Constructor that dynamically allocates some memory and initializes the member vars’ values Have a Destructor that de-allocates the memory

83 Marker Slide Any Questions on: – Making friends and overloading functions in your classes (FriendCritter) – Dynamically Allocating Memory – Memory Leaks – Using new and delete [] with arrays – Classes and Dynamic Memory – Allocation Summary – More on Classes Constructors and Destructors with Dynamic Memory Next up – More on Classes Overloading Constructors (copy constructor) Overloading the Assignment Operator Graded In-Class Activity: HeapDataMember

84 Overloading Constructors // overloading class constructors #include using namespace std; class CRectangle { int width, height; public: CRectangle (); CRectangle (int,int); int area (void) {return (width*height);} }; CRectangle::CRectangle () { width = 5; height = 5; } CRectangle::CRectangle (int a, int b) { width = a; height = b; } int main () { CRectangle rect (3,4); CRectangle rectb; cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0; } rect area: 12 rectb area: 30 Main points:

85 Overloading Constructors // overloading class constructors #include using namespace std; class CRectangle { int width, height; public: CRectangle (); CRectangle (int,int); int area (void) {return (width*height);} }; CRectangle::CRectangle () { width = 5; height = 5; } CRectangle::CRectangle (int a, int b) { width = a; height = b; } int main () { CRectangle rect (3,4); CRectangle rectb; cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0; } rect area: 12 rectb area: 30 Main points: Have a Constructor with no params, sets default values for member variables

86 Overloading Constructors // overloading class constructors #include using namespace std; class CRectangle { int width, height; public: CRectangle (); CRectangle (int,int); int area (void) {return (width*height);} }; CRectangle::CRectangle () { width = 5; height = 5; } CRectangle::CRectangle (int a, int b) { width = a; height = b; } int main () { CRectangle rect (3,4); CRectangle rectb; cout << "rect area: " << rect.area() << endl; cout << "rectb area: " << rectb.area() << endl; return 0; } rect area: 12 rectb area: 25 Main points: Have a Constructor with no params, sets default values for member variables Have a second Constructor with TWO params, sets member var values to params sent

87 Important Constructor to Overload The COPY constructor is one you almost always want to overload – This handles cases where you send a class object to a function via pass-by-value – C++ gives you an “implicit” copy constructor if you do not create one But it does not always (rarely) works the way you want or need it to – Especially when using pointers

88 Overloading the Copy Constructor // overloading class copy constructor #include using namespace std; class CRectangle { int *pWidth, *pHeight; public: CRectangle (); CRectangle (CRectangle& copyMe); CRectangle (int,int); int area (void) {return (*pWidth) * (*pHeight);} }; CRectangle::CRectangle () { pWidth = new int(5); pHeight = new int(5); } CRectangle::CRectangle (CRectangle& copyMe) { pWidth = new int(*(copyMe.pWidth)); pHeight = new int(*(copyMe.pHeight)); } CRectangle::CRectangle (int a, int b) { pWidth = new int(a); pHeight = new int(b); } rect area: 12 passed rect area: 12 Main points: [next slide] void PrintRect (CRectangle printMe) { cout << "passed rect area: " << printMe.area() << endl; } int main () { CRectangle rect (3,4); cout << "rect area: " << rect.area() << endl; PrintRect(rect); return 0; }

89 Overloading the Copy Constructor // overloading class copy constructor #include using namespace std; class CRectangle { int *pWidth, *pHeight; public: CRectangle (); CRectangle (CRectangle& copyMe); CRectangle (int,int); int area (void) {return (*pWidth) * (*pHeight);} }; CRectangle::CRectangle () { pWidth = new int(5); pHeight = new int(5); } CRectangle::CRectangle (CRectangle& copyMe) { pWidth = new int(*(copyMe.pWidth)); pHeight = new int(*(copyMe.pHeight)); } CRectangle::CRectangle (int a, int b) { pWidth = new int(a); pHeight = new int(b); } rect area: 12 passed rect area: 12 Main points: Declare copy constructor void PrintRect (CRectangle printMe) { cout << "passed rect area: " << printMe.area() << endl; } int main () { CRectangle rect (3,4); cout << "rect area: " << rect.area() << endl; PrintRect(rect); return 0; }

90 Overloading the Copy Constructor // overloading class copy constructor #include using namespace std; class CRectangle { int *pWidth, *pHeight; public: CRectangle (); CRectangle (CRectangle& copyMe); CRectangle (int,int); int area (void) {return (*pWidth) * (*pHeight);} }; CRectangle::CRectangle () { pWidth = new int(5); pHeight = new int(5); } CRectangle::CRectangle (CRectangle& copyMe) { pWidth = new int(*(copyMe.pWidth)); pHeight = new int(*(copyMe.pHeight)); } CRectangle::CRectangle (int a, int b) { pWidth = new int(a); pHeight = new int(b); } rect area: 12 passed rect area: 12 Main points: Declare copy constructor Implement the copy constructor void PrintRect (CRectangle printMe) { cout << "passed rect area: " << printMe.area() << endl; } int main () { CRectangle rect (3,4); cout << "rect area: " << rect.area() << endl; PrintRect(rect); return 0; }

91 Overloading the Copy Constructor // overloading class copy constructor #include using namespace std; class CRectangle { int *pWidth, *pHeight; public: CRectangle (); CRectangle (CRectangle& copyMe); CRectangle (int,int); int area (void) {return (*pWidth) * (*pHeight);} }; CRectangle::CRectangle () { pWidth = new int(5); pHeight = new int(5); } CRectangle::CRectangle (CRectangle& copyMe) { pWidth = new int(*(copyMe.pWidth)); pHeight = new int(*(copyMe.pHeight)); } CRectangle::CRectangle (int a, int b) { pWidth = new int(a); pHeight = new int(b); } rect area: 12 passed rect area: 12 Main points: Declare copy constructor Implement the copy constructor Verify the copy constructor works void PrintRect (CRectangle printMe) { cout << "passed rect area: " << printMe.area() << endl; } int main () { CRectangle rect (3,4); cout << "rect area: " << rect.area() << endl; PrintRect(rect); return 0; }

92 Marker Slide Any Questions on: – Making friends and overloading functions in your classes (FriendCritter) – Dynamically Allocating Memory – Memory Leaks – Using new and delete [] with arrays – Classes and Dynamic Memory – Allocation Summary – More on Classes Constructors and Destructors with Dynamic Memory Overloading Constructors (copy constructor) Next up – More on Classes Overloading the Assignment Operator Graded In-Class Activity: HeapDataMember

93 Important Operator to Overload The Assignment Operator is one you almost always want to overload – operator= – This handles cases where you set one variable equal to another myClass A(1,2); myClass B(6,7) A = B cout << A; // expect 6 and 7 to be printed out – C++ gives you an “implicit” assignment operator if you do not create one But it does not always (rarely) works the way you want or need it to

94 Overloading operator= For this example we will overload the assignment operator as a member function – you can make the operator a friend function also – but this is the “other way” Some code has been omitted, to focus on the important parts =) int main() { MyClass c1, c2; c1 = c2; // assigns c2 to c1 } The Goal is to be able to do this

95 Overloading operator= For this example we will overload the assignment operator as a member function – you can make the operator a friend function also – but this is the “other way” Some code has been omitted, to focus on the important parts =) int main() { MyClass c1, c2; c1 = c2; // assigns c2 to c1 } The Goal is to be able to do this Assume we have a class that has private members: int x, char c, std::string s And a constructor that works like this: MyClass c1; c1 = MyClass( 5, 'a', "Hello World" );

96 Overloading operator= For this example we will overload the assignment operator as a member function – you can make the operator a friend function also – but this is the “other way” Some code has been omitted, to focus on the important parts =) int main() { MyClass c1, c2; c1 = c2; // assigns c2 to c1 } The Goal is to be able to do this Assume we have a class that has private members: int x, char c, std::string s And a constructor that works like this: MyClass c1; c1 = MyClass( 5, 'a', "Hello World" ); Then to override the assignment operator as a member function we would need to implement it like this: MyClass& MyClass::operator=( const MyClass& rhs ) { x = other.x; c = other.c; s = other.s; return *this; }

97 Overloading operator= For this example we will overload the assignment operator as a member function – you can make the operator a friend function also – but this is the “other way” Some code has been omitted, to focus on the important parts =) int main() { MyClass c1, c2; c1 = c2; // assigns c2 to c1 } The Goal is to be able to do this Assume we have a class that has private members: int x, char c, std::string s And a constructor that works like this: MyClass c1; c1 = MyClass( 5, 'a', "Hello World" ); Then to override the assignment operator as a member function we would need to implement it like this: MyClass& MyClass::operator=( const MyClass& rhs ) { x = other.x; c = other.c; s = other.s; return *this; } In the class declaration we would need the line: MyClass& operator=( const MyClass& rhs )

98 Marker Slide Any Questions on: – Making friends and overloading functions in your classes (FriendCritter) – Dynamically Allocating Memory – Memory Leaks – Using new and delete [] with arrays – Classes and Dynamic Memory – Allocation Summary – More on Classes Constructors and Destructors with Dynamic Memory Overloading Constructors (copy constructor) Overloading the Assignment Operator Next up – More on Classes Graded In-Class Activity: HeapDataMember

99 Download the file: – ICA015_BrokenHeapDataMember.cpp Rename it: HeapDataMember.cpp Fix the program as indicated – Compile it – Run it – When satisfied with it (or out of time) upload the resulting FIXED code to the appropriate D2L dropbox You can work in groups – BUT each individual must submit something to D2L

100 Marker Slide Any questions on: – Making friends and overloading functions in your classes (FriendCritter) – Dynamically Allocating Memory – Memory Leaks – Using new and delete [] with arrays – Classes and Dynamic Memory – Allocation Summary – More on Classes Constructors and Destructors with Dynamic Memory Overloading Constructors (copy constructor) Overloading the Assignment Operator Graded In-Class Activity: HeapDataMember Any General Questions? Next Up – Free Play

101 Free Play – Things to Work On Graded In-Class Activity: HeapDataMember Homework 4 Homework 5 Various In-Class Activities to revisit Several On-Your Own Activities

102 The End Or is it?


Download ppt "Advanced Classes and Dynamic Memory Allocation Data Structures and Algorithms CS 244 Brent M. Dingle, Ph.D. Department of Mathematics, Statistics, and."

Similar presentations


Ads by Google