You are on page 1of 18

Constructors & Destructors

Controlling initialization & destruction


Operator Overloading
• Most operators in C++ can be overloaded
• Two ways:
• Member function of user defined class
• Non-member "stand alone" function
• Any operator overloading has to involve a
user-defined class object
• Has to be at least one operand that is not built-in
• Most operators are binary (i.e. the have a left and
a right-hand side), and the expression
Operator Overloading
• x op y can be defined either
• Stand-alone function call
• operatorop(x,y);
• Member-function call for x:
• x.operatorop(y);

• If define overloaded operator as member


function, it must be member function of
left-hand-side object
Interface & Implementation
• We want to limit access to data members
• Done with private keyword
• We want to separate interface from
implementation
• Constructors automatically called when new
object created
• Destructors automatically called when object
destroyed
Creation
• Objects are created in a few ways
• double x;
• Creates an object of type double

• C++ provides mechanism to control what


happens when user defined classes are
created in statement like above
• Constructor
Constructors
• Same name as class
• No return type (not even void!)
• Can be overloaded
• Same name, differ by arguments they take
• One with no arguments is “default” constructor
Example
int main()
{
ToD x, y;
return 0;
}

class ToD
{
private:
int h, m;
bool PM;
public:
ToD(){
cout << "ToD object created!" << endl;
}
};
What’s on the screen when the program runs?
Use?
(besides cheesy messages)
• Initialization
• Sometimes objects need to have values or
perform some operation before they can be
used
Isolating Implementation
• User can’t manipulate values
• User doesn’t need to do anything to
initialize

• User can’t put object in invalid state


Destructors
• Only one per class
• Class name with ~ in front
• Doesn’t take any arguments
• Controls what happens when object
destroyed
• Called automatically
Destructor Example
class Silly
{
private:
string name;
public:
Silly(){
cout <<"A silly object is born!"<< endl;
} int main()
~Silly(){ {
cout <<"Silly object "<<name<<" dies!"<< endl; Silly *p;
} if (1>0){
}; Silly first;
first.name = “Tom";
p = new Silly[2];
p[0].name = "John";
p[1].name = “Sara";
}
Silly last;
last.name = “Tom Jr";
delete [] p;
return 0;
}
Use?
• When is destructor useful?
• Executed when object destroyed
• Can do anything, but interesting when
deallocate memory
• Want to delete items created using new to free up
memory
Destructor Example
/** DEFINITION OF CLASS NODE **/
class Node {
public:
int data;
Node *next;
Node(int val, Node* p) {
data = val;
next = p;
}
}; List::~List() {
while(head != 0) {
Node *p = head;
head = head->next;
delete p;
}
}
Letting the User Define
• What about letting the user choose
initialization values?
• Example:
Point A, B, C;
A.x = 2.4;
A.y = -0.5;
B.x = 0.0;
B.y = 3.3;
C.x = (A.x + B.x)/2;
C.y = (A.y + B.y)/2;
Wouldn’t It Be Nice?
Point A(2.4,-0.5), B(0.0,3.3);
Point C((A.x + B.x)/2,(A.y + B.y)/2);

• Constructors make this possible


To the point (class)
Class Point
{
public:
double x, y;
Point() { x = y = 0; }
Point(double a)
{
x = a;
y = 0;
}
Point(double a, double b)
{
x = a;
y = b;
}
};
Calling Constructors
• Called three ways
1. Previously mentioned
• ex. Point p;
2. Using new Operator
• ex. Point *p = new Point(3.3,7.1); Class Point
{
3. As function that returns object public:
double x, y;
• Point(3.3,7.1).magnitude(); Point(double a, double b)
{
x = a;
y = b;
}
double magnitude() {
return sqrt(x*x + y*y);
}
};
Default Arguments
• In any function prototype, can follow name
of parameter with default value

Class Point
{
public:
double x, y;
Point(double a = 0, double b = 0)
{
x = a;
y = b;
}
};

You might also like