1 / 61

Classes & Dynamic Arrays

Classes & Dynamic Arrays. by Briana Morrison adapted from Dale/Weems/Headington and Cahoon/Davidson. Topics. Dynamic Arrays Class Specification Class Implementation Destructors Deep Copies Copy Constructor Assignment Operator This Pointer Inline Functions

audra
Download Presentation

Classes & Dynamic Arrays

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Classes & Dynamic Arrays by Briana Morrison adapted from Dale/Weems/Headington and Cahoon/Davidson

  2. Topics • Dynamic Arrays • Class Specification • Class Implementation • Destructors • Deep Copies • Copy Constructor • Assignment Operator • This Pointer • Inline Functions • Constructor Initialization Lists

  3. Dynamically Sized Lists • Up until now all lists (arrays) have had a fixed size, determined at compile time int a[10]; // holds maximum of 10 int and there is possible wasted space • Using dynamic memory allocation, we can size the list during execution of the program IntPtr a = new int[10];

  4. Operator new Syntax new DataType new DataType [IntExpression] If memory is available, in an area called the heap (or free store) new allocates the requested object or array, and returns a pointerto (address of ) the memory allocated. Otherwise, program terminates with error message. The dynamically allocated object exists until the delete operator destroys it.

  5. Dynamic Array Allocation char *ptr;// ptr is a pointer variable that // can hold the address of a char ptr = new char[ 5 ]; // dynamically, during run time, allocates // memory for a 5 character array // and stores the base address into ptr 6000 6000 ptr

  6. Operator delete Syntax delete Pointer delete [ ] Pointer If the value of the pointer is 0 there is no effect. Otherwise, the object or array currently pointed to by Pointer is deallocated, and the value of Pointer is undefined. The memory is returned to the free store. Square brackets are used with delete to deallocate a dynamically allocated array.

  7. A Simple Dynamic List Type • What we want • An integer list data type DynArray that allows run-time specification of size. Also prevents indexes from going out of bounds and aggregate array copying and initialization • Features and abilities • True object • Can be passed by value and reference • Can be assigned and copied • Inspect and mutate individual elements • Inspect list size • Print and read a list

  8. Sample DynArray Usage DynArray beta(5); //create array of 5 elements beta.Store (75, 2); // store value 75 at location 2 DynArray gamma(4,1); // create array of 4 elements gamma.Store (-8, 2); // store value -8 at location 2 cout << gamma.ValueAt(2); // print value at location 2 for (int i = 0, i < gamma.Size( ); i++) beta.Store(gamma.ValueAt(i), i); cout << beta << endl; gamma = beta;

  9. // SPECIFICATION FILE (dynarray.h) // Safe integer array class allows run-time specification of size, prevents // indexes from going out of bounds, allows aggregate array copying and // initialization. class DynArray { public: DynArray(/*in*/ int arrSize = 10, /*in*/ int val = 0 ); // Default Constructor. // POST: IF arrSize >= 1 && enough memory THEN // Array of size arrSize is created with all elements // == val // ELSE error message.

  10. DynArray(/*in*/ const DynArray& otherArr ); // Copy constructor. // POST: this DynArray is a deep copy of otherArr ~DynArray( ); // Destructor. // POST: Memory for dynamic array deallocated. int Size( ) const; // Inspector for size of list // POST: Number of elements of list is returned. int ValueAt (/*in*/ int i ) const; // PRE: i is assigned. // POST: IF 0 <= i < size of this array THEN // FCTVAL == value of array element at index i // ELSE error message. void Store (/*in*/ int val, /*in*/ int i ) // PRE: val and i are assigned // POST: IF 0 <= i < size of this array THEN val is // stored in array element i ELSE error message.

  11. DynArray& operator= (/*in*/ DynArray& otherArr); // Assignment Operator. // POST: IF enough memory THEN current values of array are // deallocated. new array created (as deep copy) with size // and contents same as otherArr ELSE error message. private: int *arr ; // pointer to elements int size ; // size of list }; // overload input and output operators ostream& operator<<(ostream &sout, const DynArray &A); istream& operator>>(istream &sin, DynArray &A);

  12. class DynArray DynArray Free store 6000 DynArray 80 40 90 0 0 Private data: size5 arr6000 ~DynArray DynArray ValueAt Store Size =

  13. DynArray beta(5); //constructor beta DynArray Free store 2000 DynArray 0 0 0 0 0 Private data: size5 arr 2000 ~DynArray DynArray ValueAt Store Size =

  14. DynArray::DynArray(/*in*/ int arrSize, /*in*/ int val) { int i; if ( arrSize < 1 ) { cerr << “DynArray constructor - invalid size: “ << arrSize << endl; exit(1); } arr = new int[arrSize] ; // allocate memory size = arrSize; for (i = 0; i < size; i++) arr[i] = val; } Default Constructor

  15. beta.Store (75, 2); beta DynArray DynArray Free store 2000 DynArray 0 0 75 0 0 Private data: size 5 arr 2000 ~DynArray DynArray ValueAt Store Size =

  16. int DynArray::Size ( ) { return size; } void DynArray::Store ( /* in */ int val, /* in */ int i ) { if ( i < 0 || i >= size ) { cerr << “Store - invalid index : “ << i << endl; exit(1) ; } arr[i] = val ; } Size & Store

  17. DynArray gamma(4,1); //constructor gamma beta DynArray DynArray 3000 2000 DynArray DynArray 1 1 1 1 0 0 75 0 0 Private: size 4 arr 3000 Private: size 5 arr 2000 ~DynArray ~DynArray DynArray DynArray ValueAt ValueAt Store Store Size Size = =

  18. gamma.Store(-8,2); gamma beta DynArray DynArray 3000 2000 DynArray DynArray 1 1 -8 1 0 0 75 0 0 Private: size 4 arr 3000 Private: size 5 arr 2000 ~DynArray ~DynArray DynArray DynArray ValueAt ValueAt Store Store Size Size = =

  19. cout << gamma.ValueAt (2); // -8 gamma beta DynArray DynArray 3000 2000 DynArray DynArray 1 1 -8 1 0 0 75 0 0 Private: size 4 arr 3000 Private: size 5 arr 2000 ~DynArray ~DynArray DynArray DynArray ValueAt ValueAt Store Store Size Size = =

  20. int DynArray::ValueAt ( /* in */ int i ) const { if ( i < 0 || i >= size ) { cerr << “ValueAt - invalid index : “ << i << endl; exit(1) ; } return arr[i]; } ValueAt

  21. for (int i=0; i < gamma.Size( ); i++) beta.Store (gamma.ValueAt(i), i); gamma beta DynArray DynArray 3000 2000 DynArray DynArray 1 1 -8 1 1 1 -8 1 0 Private: size 4 arr 3000 Private: size 5 arr 2000 ~DynArray ~DynArray DynArray DynArray ValueAt ValueAt Store Store Size Size = =

  22. Gang of Three Rule If a class has a data member that points to dynamic memory then that class needs a library-defined • Destructor • An anti-constructor that typically uses delete on the data members that point to dynamic memory • Copy constructor • Constructor that builds an object out of an object of the same type • Member assignment operator • Resets an object using another object of the same type as a basis

  23. Classes with Data Member Pointers Need CONSTRUCTOR COPY CONSTRUCTOR DESTRUCTOR ASSIGNMENT OP (=)

  24. Why is a destructor needed? When a DynArray class variable goes out of scope, the memory space for data members size and pointer arr is deallocated. But the dynamic array that arr points to is not automatically deallocated. If there is nothing planned, then we would have a memory leak A class destructor is used to deallocate the dynamic memory pointed to by the data member to prevent the memory leak.

  25. Destructor Rules • Same name as class, preceded by tilde (~) • cannot return anything, has no arguments • Must be public • A class object going out of scope automatically has its destructor invoked

  26. class DynArray Destructor DynArray::~DynArray( ) { delete [ ] arr ; size = 0; }

  27. Making Copies of Objects There are three ways to make a copy of an object: • explicitly upon declaration Rational p(1,2), r(p); • pass by value argument void add (Rational r); • return object from function Rational a_func( ) { return Rational(3,4); }

  28. Default Copy Constructor • Suppose we use the default copy constructor DynArray A(3, 1); DynArray B(A); • And then A[1] = 2; • Then • B[1] is changed! • Not what a client would expect • Implication • Must use tailored copy constructor

  29. What happens . . . When a function is called that uses pass by value for a class object of DynArray type? DynArray 2000 DynArray 0 0 75 0 0 Private: size 5 arr 2000 ~DynArray DynArray ValueAt Store Size =

  30. Passing a Class Object by Value // FUNCTION CODE void SomeFunc( DynArray someArr ) // Uses pass by value { . . . . }

  31. By default,Pass-by-value makes a shallow copy DynArray beta(5); // CLIENT CODE . . . SomeFunc( beta ); // function call beta someArr 2000 DynArray . . . DynArray . . . 0 0 75 0 0 Private: size 5 arr 2000 Private: size 5 arr 2000 shallow copy

  32. Shallow Copyvs.Deep Copy • a shallow copycopies only the class data members, and does not make a copy of any pointed-to data • a deep copycopies not only the class data members, but also makes a separate stored copy of any pointed-to data

  33. What’s the difference? • a shallow copyshares the pointed to dynamic data with the original class object • a deep copymakes its own copy of the pointed to dynamic data at different locations than the original class object

  34. SupposeSomeFunccalls Store // FUNCTION CODE void SomeFunc( DynArray someArr ) // Uses pass by value { someArr.Store(290, 2); . . . } WHAT HAPPENS IN THE SHALLOW COPY SCENARIO?

  35. beta.arr[2] has changed DynArray beta(5); // CLIENT CODE . . . SomeFunc( beta); beta someArr 2000 DynArray . . . DynArray . . . 0 0 290 0 0 Private: size 5 arr 2000 Private: size 5 arr 2000 shallow copy

  36. beta.arr[2] has changed NOTICE THAT NOT JUST FOR THE SHALLOW COPY, BUT ALSO FOR ARGUMENT beta, THE DYNAMIC DATA HAS CHANGED! beta someArr 2000 DynArray . . . DynArray . . . 0 0 290 0 0 Private: size 5 arr 2000 Private: size 5 arr 2000 shallow copy

  37. At the end of SomeFunc • When SomeFunc ends, what method is called? • What happens to the shared data?

  38. Making a (Separate) Deep Copy beta someArr 2000 DynArray . . . 0 0 75 0 0 Private: size 5 arr 2000 4000 DynArray . . . 0 0 75 0 0 Private: size 5 arr 4000 deep copy

  39. Initialization of Class Objects • C++ defines initialization to mean • initialization in a variable declaration • passing an object argument by value • returning an object as the return value of a function • by default, C++ uses shallow copies for these initializations

  40. As a result . . . • when a class has a data member pointer to dynamically allocated data, you should write what is called acopy constructor • the copy constructor is implicitly called in initialization situationsandmakes a deep copy of the dynamic data in a different memory location

  41. More about Copy Constructors • when there is a copy constructor provided for a class, the copy constructor is used to make copies for initialization • you do not always call the copy constructor explicitly • like other constructors, it has no return type • because the copy constructor properly defines pass by value for your class, it must use pass by reference in its definition

  42. Copy Constructor • copy constructor is a special member function of a class that is implicitly called in these 3 situations: • passing object parameters by value • initializing an object variable in its declaration • returning an object as the return value of a function

  43. SomeFunc(beta); // copy-constructor // beta passed by value beta someArr DynArray DynArray 2000 4000 DynArray DynArray 0 0 75 0 0 0 0 75 0 0 Private: size 5 arr 2000 Private: size 5 arr 4000 ~DynArray ~DynArray DynArray DynArray ValueAt ValueAt Store Store Size Size = = DEEP COPY

  44. DynArray::DynArray( const DynArray& otherArr ) { int i ; size = otherArr.Size( ) ; arr = new int[size] ; // allocate memory for copy for ( i = 0; i< size ; i++ ) arr[i] = otherArr.arr[i] ; // copies array } Copy Constructor

  45. What about the assignment operator? • the default method used for assignment of class objects makes a shallow copy • if your class has a data member pointer to dynamic data, you should overload the assignment operator to create a deep copy of the dynamic data • assignment operator function must be a member function

  46. gamma = beta; gamma beta DynArray DynArray 3000 2000 DynArray DynArray 0 0 75 0 0 0 0 75 0 0 Private: size 5 arr 3000 Private: size 5 arr 2000 ~DynArray ~DynArray DynArray DynArray ValueAt ValueAt Store Store Size Size = = DEEP COPY

  47. First Assignment Attempt • Algorithm • Return existing dynamic memory. • Acquire sufficient new dynamic memory. • Copy the size and the elements of the source object to the target element.

  48. Initial Implementation DynArray& operator=(const DynArray &A) { delete [ ] arr; size = A.Size( ); arr = new int [size]; for (int i = 0; i < size; i++) arr[i] = A.arr[i]; return A; } • Consider what happens with the code segment DynArray C(5,1); C = C;

  49. gamma = gamma; //delete [ ] arr; array is gone, nothing to copy! gamma DynArray Free store 2000 DynArray Private data: size5 arr ? ~DynArray DynArray ValueAt Store Size =

  50. This Pointer • Inside a member function or member operator this is a pointer to the invoking object DynArray::Size() { return size; } or equivalently DynArray::Size() { return this->size; }

More Related