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
class ToD
{
private:
int h, m;
bool PM;
public:
ToD(){
cout << "ToD object created!" << endl;
}
};
int main()
{
ToD x, y;
return 0;
}
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;
}
~Silly(){
cout <<"Silly object "<<name<<" dies!"<< endl;
}
};
int main()
{
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
List::~List() {
while(head != 0) {
Node *p = head;
head = head->next;
delete p;
}
}
/** DEFINITION OF CLASS NODE **/
class Node {
public:
int data;
Node *next;
Node(int val, Node* p) {
data = val;
next = p;
}
};
Calling Constructors
•Called three ways
1.Previously mentioned
•ex. Point p;
2.Using new Operator
•ex. Point *p = new Point(3.3,7.1);
3.As function that returns object
•Point(3.3,7.1).magnitude();
Class Point
{
public:
double x, y;
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;
}
};