Title: Classes with Dynamic Allocationor Runtime Array
1- Classes with Dynamic Allocation(or Run-time
Array) - Textbook page 269
2Consider Vector class
- typedef int T
- Class vector
- public
- vector( )
- vector(int n)
-
- private
- T tPtr
- int mySize
-
-
- Vectorvector( )
- tPtr 0
- mySize 0
-
- Vectorvector(int n)
- tPtr new Tn
- mySize n
-
3Data Members We will use a run-time allocated
array so that the user can specify the capacity
of the vector during run time.
// myVector.h . . .class
myVector/ Function Members /
public . . ./ Data Members/private
int myCapacity_, // capacity of
vector mySize_ // size of
vector ElementType myVec // run-time array to
store elements
4Class Constructors Want to permit declarations
such as myVector v1, v2(n) to construct v1
as a vector with some default capacity, to
construct v2 as a stack with capacity n. To
permit both forms, we use a constructor with a
default argument./ --- Class constructor ---
Precondition A myVector has been defined.
Receive Integer numElements gt 0 (default
128) Postcondition vector constructed with
capacity numElements/ myVect
or(int numElements 128) This constructor must
really construct something (and not just
initialize data members)
5myVectormyVector(int numElements) assert
(numElements gt 0) // check precondition
myCapacity_ numElements // set vector
capacity // allocate array of
this capacity myVec new ElementTypemyCapacity
_ if (myVec 0) // memory available?
cerr ltlt "Inadequate memory to allocate
\n" exit(1) // or
assert(myArrayPtr ! 0) mySize_ 0 Now a
program can use cin gtgt num myVector v1,
v2(num)v1 will be constructed as a vector with
capacity 128 and v2 will be constructed as a
vector with capacity num.
6Other myVector operations at, push_back,
pop_back, Display Their definitions require
accessing the elements of the array data member.
As we have noted, the subscript operator can
be used in the same manner for run-time allocated
arrays as for ordinary arrays, for
example// Definition of Display()void
myVectorDisplay(ostream out) for (int i
0 i lt mySize i) out ltlt myVeci ltlt endl
7Class functions needed with run-time allocated
memory
- destructor to delete the allocated memory,
and avoid memory leaks - copy constructor to make a duplicate copy of
values in allocated memory, and avoid
changing the original values - assignment to assign values from allocated
memory. not just a pointer to the original
8destructor
- syntax classname e.g. myVector()
- automatically inserted by compiler whereever the
scope of an object ends - definition destroy any dynamically allocated
memory, e.g. delete myVec
9Destructor example
For our myVector class, we use the delete
operation to deallocate the run-time array. /
--- Class destructor --- Precondition
Lifetime of myVector containing this
function should end. Postcondition The
run-time array in the myVector containing this
function has been deallocated.
--------------------------------------------------
------/ myVector() // Definition of
destructormyVectormyVector() //
destructor cout ltlt "Testing destructor
called." ltlt endl delete myVec
10copy constructor
- syntax classname(const classname original)
e.g. myVector(const myVector original) - automatically inserted by the compiler when a
temporary copy is needed - value parameters
- return value from a function
- declaration of an object with an initial value
- definition allocate memory for new dynamic
structure copy values from original into new
structure.
11Class Copy Constructor Is needed whenever a copy
of a class object must be built,which occurs ?
When a class object is passed as a value
parameter ? When a function returns a class
object ? If temporary storage of a class object
is needed ? In initializations If a class has
no copy constructor, the compiler uses a default
copy constructor that does a byte-by-byte copy
of the object. This has been adequate for
classes without dynamically allocated data, but
is not adequate for classes containing pointers
to run-time allocated arrays (or other
structures) . It gives rise to the aliasing
problem.
12Example A byte-by-byte copying of vt to produce
a copy vtCopy gives
5
2
Not correct copies of myCapacity_, mySize_, and
myVec were made, but not a copy of the run-time
allocated array. Modifying vtCopy will modify vt
also! Need to create a distinct copy of vt, in
which the array in vtCopy has exactly the same
elements as the array in vt
13Form of copy constructor ? It is a constructor
so it must be a function member, its name is the
class name, and it has no return type. ? It needs
a single parameter (source of copy) whose type is
the class this must be a reference parameter
and should be const since it does not change
this parameter or pass information back through
it.
(Otherwise it would be a value parameter, and
since a value parameter is a copy of its
argument, a call to the copy instructor will try
and copy its argument, which calls the copy
constructor, which will try and copy its
argument, which calls the copy constructor . . . )
/ --- Copy Constructor --- Precondition A
copy of a vector is needed Receive The
vector to be copied (as a const
reference parameter) Postcondition A copy
of original has been constructed.
/myV
ector(const myVector original)
14Definition of copy constructor
myVectormyVector(const myVector original) //
copy constructor cout ltlt "Testing copy
constructor called." ltlt endl myCapacity
original.myCapacity myVec new ElementType
myCapacity mySize original.mySize for
(int i 0 i lt mySize i) myVeci
original.myVeci
15assignment
- syntax classname operator (const classname
orig)e.g. myVector operator(const myVector
original) - must use the keyword this, which is a pointer
containing the address of the object itself,
e.g. if (this ! orig) ... return
this - automatically inserted by compiler in place of
assignment, e.g. vec1 vec2 replaced by
vec1.operator(vec2) - definition if not assigned to itself,
- delete old allocated memory
- allocate new memory
- copy values from original into new memory
- return the object itself
16AssignmentAnother operation that requires
special attention for classes containing pointers
to run-time arrays (or other structures). Like
the copy constructor, the default assignment
operation does byte-by-byte copying. With it,
the assignment statement v2Copy v2will
yield aliases as before the myVec data members
of both v2 and v2Copy will both point to the same
anonymous array. Need to overload the
assignment operator (operator) so that it
creates a distinct copy of the stack being
assigned. operator must be a member function.
So an assignment vtLeft vtRightwill be
translated by the compiler as vtLeft.operator(v
tRight)
17Prototype / --- Assignment Operator ---
Receive myVector vtRight (the right side of the
assignment operator Postcondition The
myVector will be a copy of vtRight Return A
reference to the current myVector
/
operator
(const myVector original)
myVector
The return type is a reference to a Vector since
operator() must return the object on the left
side of the assignment and not a copy of it (to
make chaining possible).
18Definition of operator It is quite similar to
that for the copy constructor, but there are some
differences 1. Object on the left side of the
assignment may already have a value.
Must destroy old value deallocate the old so
no memory leak and allocate a new one. 2.
Assignment must be concerned with
self-assignments vt vt. Can't destroy the
old value in this case. 3. operator() must
return the myVector containing this
function. For 3 we use the following property
of classes
Every member function of a class has access to a
(hidden) pointer constant this whose value
is the address of the object containing this
function. The expression this refers to the
object itself.
19assignment operator
- myVector myVectoroperator (const myVector
original) - if (this ! original)
- delete myVec
- myCapacity original.myCapacity
- myVec new ElementType myCapacity
- mySize original.mySize
- for (int i 0 i lt mySize i)
- myVeci original.myVeci
-
- return this