Lab #13. Examining object oriented constructs
Lab #13.1.
Destructor
In C++, class
objects can be manipulated in two ways (lab13.1.cpp):
·
“directly” (variable of type <class>; elements (fields
and methods) accessed via dot notation (.);
·
dynamically (variable of type <class>*, i.e., pointer to <class>; elements (fields and
methods) accessed via arrow (“points-to”) notation (->).
#include <iostream>
using namespace std;
class person
{
private:
char *name;
int
age;
public:
person (const char *n, int a) { init (n,a); };
person () {};
~person ();
void init (const char*, int);
void print () { cout << name << " " << age
<< endl; }
};
int main ()
{
person p;
p.init
("Liz", 19);
p.print ();
person *pp = new
person ("Peter", 20);
pp->print ();
delete pp;
return 0;
};
person::~person ()
{
cout
<< "Deleting: " << name << endl;
delete[] name;
};
void person::init
(const char *n, int a)
{
name = new char[strlen(n)+1];
strcpy
(name, n);
age = a;
}
Destructor is a method of class, which is
automatically called right before the deletion of an object. There is exactly
one and only one constructor per class.
Observe the
call of destructors in the example above – the first destructor to execute is
that of Peter, then of Liz.
That’s because for dynamic objects destructors are called explicitly
with operator delete, but for “direct” (automatic)
object – automatically at the end of the block the object is declared.
Lab #13.2.
Constructors
(lab13.2.cpp)
#include <iostream>
using namespace std;
class timesimple
{
int
hours, minutes;
public:
timesimple
(int h, int m)
{
hours = h;
minutes = m;
cout
<< "C1 " << hours << ":" << minutes
<< endl;
};
timesimple
(const timesimple &t)
{
hours = t.hours + 1;
minutes = t.minutes + 1;
cout
<< "C2 " << hours << ":" << minutes
<< endl;
};
timesimple
(int h): hours(h), minutes(0)
{
cout
<< "C3 " << hours << ":" << minutes
<< endl;
};
timesimple
()
{
cout
<< "C4" << endl;
};
void print () const;
};
int main ()
{
timesimple
t (8, 20);
t.print ();
timesimple
u = t;
u.print ();
timesimple
v;
v = t;
v.print ();
timesimple
w = 23;
w.print ();
return 0;
};
void timesimple::print
() const
{
cout
<< hours << ":" << minutes << endl;
}
Constructor is a method, which is automatically
called right before the creation of an object. Unlike destructors, a class can
contain several constructors (but at least one). Specific constructors are
those with exactly one parameter, because they can be called implicitly
by object’s initialization (during declaration) or passing an object by value
through parameter.
Observe the call
of constructors here – especially of those with one parameter (C2, C3).
Lab #13.3.
Examining creation of a dynamic array
(lab13.3.cpp)
#include <iostream>
using namespace std;
class dynamicarray
{
int
Size;
int
*Array;
public:
dynamicarray
(int s=0)
{
Size = s;
if (Size >
0) Array = new int[Size];
};
~dynamicarray ()
{
if (Size >
0)
{
cout << Size << " elements
deleted." << endl;
delete[]
Array;
}
};
void append (int value)
{
int
*tmparray = new int[Size+1];
for (int i=0; i<Size;
i++) tmparray[i] = Array[i];
tmparray[Size] = value;
Size++;
delete[]
Array;
Array = tmparray;
};
void print ()
{
for (int i=0; i<Size;
i++) cout << Array[i] << endl;
};
int&
operator[] (int i) { return
Array[i]; };
};
int main ()
{
dynamicarray
arri(2);
arri[0] = 11;
arri[1] = 22;
arri.append (33);
arri.print ();
return 0;
}
A true sense for a destructor actually appears almost only if an object
contains dynamic structures (or operates over some other resources), and the
destructor is the right place to specify which dynamic structures should be
deleted by the deletion of the object.
The current
example contains a simplified implementation of a dynamic array of int and demonstrates the meaningful usage of
destructor. In addition, the example contains overloading of operator []
for convenient access of elements of dynamicarray
objects.