0% found this document useful (0 votes)
2 views64 pages

Operator Overloading

The document discusses operator overloading in C++, which allows programmers to redefine the behavior of existing operators for user-defined types. It explains the concept of compile-time polymorphism and provides examples of how operators like + and - can be overloaded for classes such as Complex and Distance. Additionally, it outlines the syntax for creating member operator functions and emphasizes the importance of maintaining logical consistency when overloading operators.

Uploaded by

f2024065470
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPSX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views64 pages

Operator Overloading

The document discusses operator overloading in C++, which allows programmers to redefine the behavior of existing operators for user-defined types. It explains the concept of compile-time polymorphism and provides examples of how operators like + and - can be overloaded for classes such as Complex and Distance. Additionally, it outlines the syntax for creating member operator functions and emphasizes the importance of maintaining logical consistency when overloading operators.

Uploaded by

f2024065470
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPSX, PDF, TXT or read online on Scribd
You are on page 1/ 64

Operator Overloading

By
Dr. Muhammad Nadeem Ashraf
Operator Overloading
• It is an idea of giving special meaning to an existing operator in C++
without changing its original meaning.
• Operators are predefined for certain data types like + (addition) for
numeric data, . (DOT) for objects etc.
• Operator overloading is a compile-time polymorphism.
• C++ facilitates programmers to define the behavior of well known
operators for user-defined types (classes) known as operator
overloading.
• Classes where arithmetic operators may be overloaded are Complex
Numbers, Fractional Numbers, Big integers, etc.
Operator Overloading
• Examples: Here, variables “a” and “b” are of types “int” and “float”, which are built-
in data types.
int a; Hence the addition operator ‘+’ can easily add the contents of “a” and
float b, sum; “b”.
sum = a + b; This is because the addition operator “+” is predefined to add variables of
built-in data type only.

Here, variables “s1” and “s2” are of type “string”.


The + operator can be used between strings to add them together to
make a new string due to its pre-defined ability. This is called
concatenation.
A string in C++ is actually an object, which contain functions that can
perform certain operations on strings.
For example, you can also concatenate strings with the append() function:
string firstName = “Hafiz ";
string lastName = “Awais";
string fullName
= firstName.append(lastName);
Why Operator Overloading?
• Let’s say we have defined a class Integer for handling operations on
integers.
• We can have functions add(), subtract(), multiply() and divide() for
handling the respective operations.
• However, to make the code more intuitive and enhance readability, it
is preferred to use operators that correspond to the given
operations(+, -, *, / respectively) i.e.
Replace
i5 = divide(add(i1, i2), subtract(i3,
i4))

by a simpler code:
i5 = (i1 + i2) / (i3 - i4)
Operator Overloading
// Example Program to Demonstrate the working/Logic behind Operator Overloading
class A {
//statements; In this example, we have 3 variables “a1”, “a2” and “a3” of type “class
}; A”.
Here we are trying to add two objects “a1” and “a2”, which are of user-
int main() defined type i.e. of type “class A” using the “+” operator.
{ This is Not allowed, because the addition operator “+” is predefined to
A a1, a2, a3; operate only on built-in data types.
But here, “class A” is a user-defined type, so the compiler generates an
a3 = a1 + a2; error. This is where the concept of “Operator overloading” comes in.

return 0; Now, if the user wants to make the operator “+” add two class objects,
} the user has to redefine the meaning of the “+” operator such that it adds
two class objects.
This is done by using the concept of “Operator overloading”.
So the main idea behind “Operator overloading” is to use C++ operators
with class variables or class objects.
Redefining the meaning of operators really does not change their original
Operator Overloading
• If we create a class Complex with behavior similar to complex
numbers (in mathematics domain), it would be more natural to
overload + operator enabling programmers to write statements like
mathematical expression making it a lot more readable.
• Which of the below expressions is more readable???
Sum.calculateSum(c1, c2); Sum = c1 + c2;

Use operator overloading to improve readability.


Operator Overloading in C++
// C++ Program to Demonstrate Operator Overloading
#include <iostream>
using namespace std;

class Complex {
private:
int real, imag; int main()
{
public: Complex c1(10, 5), c2(2, 4);
Complex(int r = 0, int i = 0) Complex c3 = c1 + c2; Output:
{ c3.print(); 12 + i9
real = r; }
imag = i;
}

// This is automatically called when '+' is used between two Complex objects
Complex operator+(Complex const& obj)
{
Complex res;
res.real = real + obj.real;
res.imag = imag + obj.imag;
return res;
}
void print() { cout << real << " + i" << imag << '\n'; }
};
Member Operator Function … Syntax
return-type Class-Name::operator (arguments-list) {
// body goes here
}
One can see that the overloaded operator looks like a function with slight
differences of syntax
Format
• write function definition as normal
• function name is keyword operator followed by the symbol for the
operator being overloaded.
operator+ would be used to overload the addition operator (+).
Though mostly overloaded operators return object types but C++ allows
any valid type. For example, it is more natural when two Complex objects
are added using + overloaded-operator, to return an object of Complex
type
Member Operator Function … Syntax
Member Operator Function … Example

 One can see that in loc class, overloading of + operator takes only one
loc object as parameter but when we use if main() it receives two
parameters ob1 and ob2.
 The reason for this difference is that ob1 is an invoker for + operator
and it is passed to the overloaded member implicitly by compiler.
Operator Overloading
• The assignment operator (=) may be used with every class
without explicit overloading
• Member wise assignment
• The same is true for the address operator (&)
Overloading Binary Operator
Explanation:
1.Line: Distance operator+(Distance &d2): Here return type of function is
• In the
distance and itbinary
uses call by operator
references to overloading
pass an argument.function, there
should
2.Line: d3be= d1 one+ d2:argument
Here, d1 calls tothebeoperator
passed.
function of its class object and
takes d2 as a parameter, by which the operator function returns the object and the
• It iswillthe
result reflect overloading
in the d3 object.of an operator operating on two
// C++ program to show binary operator overloading Output:
operands.
#include <iostream>
Total Feet & Inches:
using namespace std; // Overloading (+) operator to perform addition of
two distance // object Call by reference 18'11
class Distance { Distance operator+(Distance& d2) // Driver Code
public: { int main()
int feet, inch; // Create an object to return {
Distance d3; Distance d1(8, 9);
Distance() Distance d2(10, 2);
{ Distance d3;
this->feet = 0; d3.feet = this->feet + d2.feet;
this->inch = 0; d3.inch = this->inch + d2.inch; // Use overloaded operator
} d3 = d1 + d2;
Distance(int f, int i) // Return the resulting object
{ return d3; cout << "\nTotal Feet & Inches: " << d3.feet <<
this->feet = f; } "'" << d3.inch;
this->inch = i; }; return 0;
}
Overloading Unary Operator
• Let us consider overloading (-) unary operator. In the unary
operator function, no 2nd arguments should be passed.
• It works only with one class object. It is the overloading of
an operator operating on a single operand.
• Example:
• Assume that class Distance has two member objects i.e.
feet and inches
• Creates a function by which the Distance object should
decrement the value of feet and inches by 1 (having a
single operand of Distance Type).
Overloading Unary Operator
// C++ program to show unary operator overloading
#include <iostream>
using namespace std;
// Driver Code
class Distance { int main()
public: {
int feet, inch; Distance d1(8, 9);

// Constructor to initialize the object's value Output:


// Using (-) unary operator by
Distance(int f, int i) single operand Feet &
{
this->feet = f;
-d1; Inches(Decrement):
return 0;
this->inch = i; } 7'8
}

// Overloading(-) operator to perform decrement operation of


Distance object Explanation: This program shows that no argument is passed and
void operator-() no return_type value is returned, because the unary operator works
{ on a single operand. (-) operator changes the functionality to its
feet--; member function.
inch--;
cout << "\nFeet & Inches(Decrement): " << feet << "'" <<Note: d2 = -d1 will not work, because operator-() does not return any value.
inch;
}
};
Member Operator Function … Important Point

Though it is technically possible to perform completely a different


operation in its implementation from operator to be overloaded but not
only that it is illogical but also it makes your program confusing and hard
to maintain
1) For operator overloading to work, at least one of the operands must be
a user-defined class object.
2) Assignment Operator: Compiler automatically creates a default
assignment operator with every class. The default assignment operator
does assign all members of the right side to the left side and works fine in
most cases (this behavior is the same as the copy constructor). See this
for more details.
Member Operator Function …
Important Point
3) Conversion Operator: We can also write conversion operators
that can be used to convert one type to another type.
// C++ Program to Demonstrate the working of conversion operator
#include <iostream>
using namespace std;
class Fraction { int main()
private:
int num, den; {
Fraction f(2, 5);
public: float val = f;
Fraction(int n, int d)
{
cout << val
num = n; << '\n'; Output
den = d; return 0; 0.4
} }
// Conversion operator: return float value of
fraction
operator float() const Overloaded conversion operators must be a
{ member method.
return float(num) / float(den);Other operators can either be the member
}
};
method or the global method.
Member Operator Function …
Important Point
4) Any constructor that can be called with a single argument
works as a conversion constructor, which means it can also be
used for implicit conversion to the class being constructed.
// C++ program to demonstrate can also be used for implicit conversion to the class
being constructed
#include <iostream> int main()
using namespace std; {
class Point { Point t(20, 20);
private: t.print();
int x, y; t = 30; // Member x of t
public:
becomes 30
Point(int i = 0, int j = 0) t.print();
{ return 0;
x = i; }
y = j; Output:
} x = 20, y = 20 x = 30, y
void print() = 0
{
cout << "x = " << x << ", y = " << y << '\n';
}
Can We Overload All Operators?
• Almost all operators can be
overloaded except a few.

Following is the list of operators that cannot be


overloaded.
1. sizeof
2. typeid
3. Scope resolution (::)
4. Class member access operators (.(dot), .* (pointer to
member operator))
5. Ternary or conditional (?:)

See details after Next few slides


Member Operator Function … Task
Create a location class as used in previous example. Overload
different operators including +, +=, -, -=, = , -- and ++.
1. + operator adds two locations one invoker and one parameter. It
returns their sum.
2. += operator adds two locations one invoker and one parameter. It
stores the sum into invoker.
3. - operator subtracts two locations one invoker and one parameter. It
returns their difference.
4. -= operator subtracts two locations one invoker and one parameter.
It stores the difference into invoker.
5. = operator the values of parameter object into invoker object.
6. ++ operator adds 1 to the both data members of the invoker. It
returns the incremented object too.
7. -- operator subtracts 1 from the both data members of the invoker. It
returns the incremented object too.
Overloading (++) Pre Increment
Prefix ++ Increment Operator Overloading
with no return type
Overloading (++) Pre Increment
Prefix ++ Increment Operator Overloading
with return type
• Here is the little modification of
previous program so that you can
use the code
obj1 = ++obj.
The only difference is that, the return type of
operator function is class Check in this case which
allows to use both codes:
++obj; and obj1 = ++obj;.
It is because, temp returned from operator function
is stored in object obj.

Since, the return type of operator function is


Check, you can also assign the value of obj to
another object.

Notice that, = (assignment operator) does not


Overloading (++) Pre Increment
Prefix ++ Increment Operator Overloading
with return type
• More appropriate is to use this pointer
Overloading Post Increment (++)
Comparison: Pre/Post Increment
Operators
Comparison: Pre/Post Increment
Operators
• Overloading the Increment Operator
• The operator symbol for both prefix(++i) and postfix(i++)
are the same.
• Hence, we need two different function definitions to distinguish
between them.
• This is achieved by passing a dummy int parameter in the
postfix version.
• Notice, the int inside bracket.
• This int gives information to the compiler that it is the postfix
version of operator.
• Don't confuse this int doesn't indicate integer.
Overloading ++ and --
• Pre/post-incrementing/decrementing operators are allowed to be
overloaded.
• How does the compiler distinguish between “pre” and “post”
versions of the operators?
• prefix versions overloaded same as any other prefix unary operator would be. i.e.
d1.operator++(); for ++d1.
• convention adopted that when compiler sees post incrementing
expression, such as
d1++
• it will generate the member-function call
d1.operator++( 0 )
• whose prototype is
Date::operator++( int ).
Both Pre/Post Increment Operators
• Program to make this work
both for prefix form and
postfix form.
Try to implement it with this pointer.
Exercise
• Overloading both Pre/Post
Decrement (--) Operators
Member Operator Function … Task … Implementation
Create a location class as used
in previous example. Overload
different operators including
+, +=, -, -=, = , -- and ++.

loc class
Member Operator Function … Task … Implementation
Create a location
class as used in
previous example.
Overload different
operators
including +, +=, -,
-=, = , -- and ++.

main() method to
test the
functionality of loc
class.
Member Operator Function … Task … Implementation
Create a location
class as used in
previous example.
Overload different
operators
including +, +=, -,
-=, = , -- and ++.

Constructors,
Setters and
show() method
implementation in
loc class
Member Operator Function … Task … Implementation
Create a location
class as used in
previous example.
Overload different
operators
including +, +=, -,
-=, = , -- and ++.
&

+ and +=
operators
overloading
implementation in Similar implementation for – and
loc class -= operators.
Member Operator Function … Task … Implementation
Create a location
class as used in
previous example.
&

Overload different
operators
including +, +=, -,
-=, = , -- and ++. &

++, -- and =
operators
overloading
implementation in
loc class
Restrictions on Operators Overloading
The precedence of an operator cannot be changed
The number of operands for an operator cannot be changed. One
might effectively reduce the operands by ignoring them.
Overloaded operators cannot have default arguments ... (the exception of
the operand that is a function call)
Few operators cannot be overloaded in C++
1. sizeof
2. typeid
3. Scope resolution (::)
4. Class member access operators (.(dot), .* (pointer to member operator))
5. Ternary or conditional (?:)
Why can’t the above-stated
operators be overloaded? // C++ program to demonstrate operator overloading using dot
operator
#include <iostream> int main()
using namespace std; {
Explanation:
1. sizeof Operator ComplexNumber c1(3,
The statement
This returns ComplexNumber
the size c3 =class
of the object or datatype c1 + c2;asisthe operand.
entered
ComplexNumber { This 5);
is evaluated by the compiler and
internally translated as ComplexNumber
cannot be evaluated during runtime. The proper c3
private: =
incrementing of a pointer in an arrayComplexNumber
of objects reliesc2(2,
on
the sizeof operator implicitly. Altering its meaning using
intoverloading 4);
would cause a fundamental part of the
c1.operator+ (c2); in order to invoke the operator real;
language to collapse. int imaginary; ComplexNumber c3 = c1
function. + c2;
2. typeid Operator
The argument c1 is implicitly passed public: using c3.print();
This provides a CPP program with the ability to recover the actually derived type of the object
return 0; referred to by
Output:
the ‘.’ operator. ComplexNumber(int real,
a pointer or reference. For this operator, the whole point is to uniquely identify int
a imaginary)
type. If we want to make 5a + i9
{ }
The next statement
user-defined alsoanother
type ‘look’ like makes usepolymorphism
type, of the dot can be used but the meaning of the typeid
operator must remain unaltered, or else serious issues this->real = real;
operator to access the member function print could
and arise.
this->imaginary = imaginary;
3. Scope
pass c3 asresolution (::) Operator
an argument. }
This helps identify and specify the context to
Besides, these operators also work on namesvoid which an identifier
andprint()refers
{ coutby
<<specifying
real << " a
+ namespace. It is }
i" << imaginary;
completely evaluated at runtime and works on names ComplexNumber
rather than values. The operands of scope c2)
operator+(ComplexNumber resolution
not values and there is no provision (syntactically)
are note expressions with data types and CPP has no syntax for capturing them if it were overloaded. So it is
{
to overloadimpossible
syntactically them. to overload this operator. ComplexNumber c3(0, 0);
4. Class member access operators (.(dot), .* (pointer to member operator))
c3.real = this->real + c2.real;
c3.imaginary
The importance and implicit use of class member access operators = this->imaginary
can be understood through+the following
example: c2.imaginary;
Example: return c3;
}
};
Why can’t the above-stated
operators be overloaded?
5. Ternary or conditional (?:) Operator
The ternary or conditional operator is a shorthand representation of an if-else
statement.
In the operator, the true/false expressions are only evaluated on the basis of the truth
conditional
value statementexpression.
of the conditional ? expression1 (if statement is TRUE) : expression2
(else)

A function overloading the ternary operator for a class say ABC using the definition
ABC operator ?: (bool condition, ABC trueExpr, ABC falseExpr);

would not be able to guarantee that only one of the expressions was evaluated. Thus,
the ternary operator cannot be overloaded.
Operator Overloading using Friend Functions
1. An operator can be overloaded using a non-member function,
which is usually a friend function
2. Since a friend function is a non-member for a class, it does not
have this pointer
3. Since a friend function does not have this pointer, the concept
of invoker object is not relevant here. So a friend function
defining two operands will have two parameters.
4. When a friend function is overloading a binary operator, the
very first parameter will be treated as the left operand of the
operator and the second parameter will be treated as the right
side operand.
5. Similarly, a unary operator overloaded with a friend function
will have one parameter.
Operator Overloading using Friend Functions
Syntax:

class class-name {

public:
friend return-type operator opr (parameter-list);

};
Operator Overloading using Friend Functions
Syntax:

class class-name {

public:
friend return-type operator opr (parameter-list);

};
Operator Overloading using Friend
Functions: Example
#include <iostream>
using namespace std;
class Complex { int main()
private: {
int real, imag; Complex c1(10, 5), c2(2, 4);
Complex c3 = c1 + c2; // An example call
public: to "operator+"
Complex(int r = 0, int i = 0) c3.print();
{ return 0;
real = r; }
imag = i;
}
void print() { cout << real << " + i" << imag << endl; } Output:
// The global operator function is made friend of this 12 + i9
// class so that it can access private members
friend Complex operator+(Complex const& c1, Complex
const& c2);
};  Both Two Objects (c1 and c2) are passed
Complex operator+(Complex const& c1, Complex const& c2)
{
in case of
return Complex(c1.real + c2.real, c1.imagoverladed
+ c2.imag);operator (+) using friend functions
}
Operator Overloading using Friend Functions
Code

Example
Restrictions on Friend Functions
1. =, (), [] and  operators cannot be overloaded using friend
functions
2. When overloading the increment or decrement operators, one
will need to use a reference parameter when using a friend
function
Operator Overloading using Friend Functions
Code

Example
Overloading Unary Operators

• overloading unary operators


• avoid friend functions and friend classes unless absolutely necessary.
• use of friends violates the encapsulation of a class.
• As a member function:
class String {
public:
bool operator!() const;
...
};
Overloading Stream-Insertion and
Stream-Extraction Operators
• The overloaded << and >> operators must have left
operand of types ostream &, istream & respectively.
• It must be a non-member function (left operand not an object of the class).

• It must be a friend function if it accesses private data members


1 // Fig. 8.3: fig08_03.cpp
2 // Overloading the stream-insertion and Outline
3 // stream-extraction operators.
4 #include <iostream>
1. Class definition
5
6 using std::cout;
7 using std::cin;
1.1 Function definitions
8 using std::endl;
9 using std::ostream;
10 using std::istream;
11
Notice function prototypes for
12 #include <iomanip>
13
overloaded operators >> and <<
14 using std::setw; They must be friend functions.
15
16 class PhoneNumber {
17 friend ostream &operator<<( ostream&, const PhoneNumber & );
18 friend istream &operator>>( istream&, PhoneNumber & );
19
20 private:
21 char areaCode[ 4 ]; // 3-digit area code and null
22 char exchange[ 4 ]; // 3-digit exchange and null
23 char line[ 5 ]; // 4-digit line and null
24 };
25
26 // Overloaded stream-insertion operator (cannot be
27 // a member function if we would like to invoke it with
28 // cout << somePhoneNumber;).
29 ostream &operator<<( ostream &output, const PhoneNumber &num )
 2000 Deitel
30 {& Associates, Inc. All
31 output << "(" << num.areaCode << ") "
32 << num.exchange << "-" << num.line; Outline
33 return output; // enables cout << a << b << c;
34 }
35
1.1 Function definition
36 istream &operator>>( istream &input, PhoneNumber &num )
37 {
38 input.ignore(); // skip ( 1.2 Initialize variables
39 input >> setw( 4 ) >> num.areaCode; // input area code
40 input.ignore( 2 ); // skip ) and space
41 input >> setw( 4 ) >> num.exchange; // input exchange 2. Get input
42 input.ignore(); // skip dash The
(-) function call
43 input >> setw( 5 ) >> num.line; // input line
cin >> phone;
44 return input; // enables cin >> a >> b >> c; 2.1 Assign to object
45 } interpreted as
46
operator>>(cin, phone);
47 int main() 2.2 Output data
48 { input is an alias for cin, and num
49 PhoneNumber phone; // create object phone is an alias for phone.
50
51 cout << "Enter phone number in the form (123) 456-7890:\n";
52
53 // cin >> phone invokes operator>> function by
54 // issuing the call operator>>( cin, phone ).
55 cin >> phone;
56
57 // cout << phone invokes operator<< function by
58 // issuing the call operator<<( cout, phone ).
59 cout << "The phone number entered was: " << phone << endl;
60 return 0;
 2000 Deitel
61 }& Associates, Inc. All
Enter phone number in the form (123) 456-7890:
Outline
(800) 555-1212
The phone number entered was: (800) 555-1212 Program Output

 2000 Deitel & Associates, Inc. All


Overloading new and delete keywords
It is possible to overload new and delete.
One might choose to do this if he wants to use some special
memory allocation/de-allocation method.
For example, you may want allocation routines that
automatically begin using a disk file as virtual memory when the
heap has been exhausted.
Whatever the reason, it is a very simple matter to overload these
operators.
Overloading new and delete keywords
It is possible to overload new and delete.
One might choose to do this if he wants to use some special
memory allocation/de-allocation method.
For example, you may want allocation routines that
automatically begin using a disk file as virtual memory when the
heap has been exhausted.
Whatever the reason, it is a very simple matter to overload these
operators.
Overloading some Special Operators
C++ defines array subscripting, function calling, and class
member access as operations.
The operators that perform these functions are the [ ], ( ), and –
>, respectively.
These rather exotic operators may be overloaded in C++,
opening up some very interesting uses.
One important restriction applies to overloading these three
operators: They must be non-static member functions.
They cannot be friends.
Overloading []
When you are overloading [] in C++, it is considered as a binary
operator
The general form of this overloaded operator is:

type class-name::operator[](int i){


// do something useful here
}

The parameter does not have to be of type int, but an operator[ ]


( ) function is typically used to provide array subscripting i.e.
integer value
Overloading []
Given an object say X, then the expression X[3] will be translated as:
X.operator[](3)
Overloading ()
When you overload the ( ) function call operator, you are not,
per se, creating a new way to call a function.
Rather, you are creating an operator function that can be passed
an arbitrary number of parameters.
Say we define the following overloaded operator function
declaration inside a class.
double operator()(int a, float f, char *s);
If we have an object of that class (say X) then the statement:
X(10, 2.5, “welcome”);
Will be translated as: X.operator()(10, 2.5, “welcome”)
Overloading 
In C++ the pointer operator  is considered as a unary operator
Its general usage is: objectmember
The operator() function must return a pointer to an object of a
class this operator is define in
Overloading Comma Operator
You can overload C++'s comma operator.
The comma is a binary operator, and like all overloaded
operators, you can make an overloaded comma perform any
operation you want.
If you want the overloaded comma to perform in a fashion
similar to its normal operation, then your version must discard
the values of all operands except the rightmost.
The rightmost value becomes the result of the comma operation.
This is the way the comma works by default in C++.
Criteria/Rules to Define the Operator
Function
1. In the case of a non-static member function, the binary
operator should have only one argument and the unary
should not have an argument.
2. In the case of a friend function, the binary operator should
have only two arguments and the unary should have only
one argument.
3. Operators that cannot be overloaded are .* :: ?:
4. Operators that cannot be overloaded when declaring that
function as friend function are = () [] ->.
5. The operator function must be either a non-static (member
function), global free function or a friend function.
Case Study: A Date Class

• Create a Date class


– overloaded increment operators (change day, month, or year)
– overloaded +=
– function to test for leap years
– function to determine if a day is last day of a month

 2000 Deitel & Associates, Inc. All rights


1 // Fig. 8.6: date1.h
2 // Definition of class Date Outline
3 #ifndef DATE1_H
4 #define DATE1_H
5 #include <iostream>
1. Class definition
6
7 using std::ostream; 1.1 Member functions
8
9 class Date {
1.2 Member variables
10 friend ostream &operator<<( ostream &, const Date & );
11
12 public:
13 Date( int m = 1, int d = 1, int y = 1900 ); // constructor
14 void setDate( int, int, int ); // set the date
15 Date &operator++(); // preincrement operator
16 Date operator++( int ); // postincrement operator
17 const Date &operator+=( int ); // add days, modify object
18 bool leapYear( int ) const; // is this a leap year?
19 bool endOfMonth( int ) const; // is this end of month?
20
21 private:
22 int month;
23 int day;
24 int year;
25
26 static const int days[]; // array of days per month
27 void helpIncrement(); // utility function
28 };
29
 2000 Deitel30&#endif
Associates, Inc. All rights
31 // Fig. 8.6: date1.cpp
32 // Member function definitions for Date class Outline
33 #include <iostream>
34 #include "date1.h"
35 1. Load header
36 // Initialize static member at file scope;
37 // one class-wide copy.
38 const int Date::days[] = { 0, 31, 28, 31, 30, 31, 30, 1.1 Define days[]
39 31, 31, 30, 31, 30, 31 };
40
1.2 Function definitions
41 // Date constructor
42 Date::Date( int m, int d, int y ) { setDate( m, d, y ); }
43 1.3 Constructor
44 // Set the date
45 void Date::setDate( int mm, int dd, int yy )
46 { 1.4 operator++
47 month = ( mm >= 1 && mm <= 12 ) ? mm : 1; (preincrement)
48 year = ( yy >= 1900 && yy <= 2100 ) ? yy : 1900;
49
50 // test for a leap year
51 if ( month == 2 && leapYear( year ) )
52 day = ( dd >= 1 && dd <= 29 ) ? dd : 1;
53 else
54 day = ( dd >= 1 && dd <= days[ month ] ) ? dd : 1;
55 }
56
57 // Preincrement operator overloaded as a member function.
58 Date &Date::operator++()
59 {
60 helpIncrement();
61 return *this; // reference return to create an lvalue
62 }
 2000 Deitel63& Associates, Inc. All rights
64 // Postincrement operator overloaded as a member function.
65 // Note that the dummy integer parameter does not have a Outline
66 // parameter name.
67 Date Date::operator++( int )
68 { 1.5 operator++(int)
69 Date temp = *this; postincrement operator
(postincrement)
70 helpIncrement(); has a dummy int value
71
72 // return non-incremented, saved, temporary object 1.6 operator+=
73 return temp; // value return; not a reference return
74 }
75 1.7 leapYear
76 // Add a specific number of days to a date
77 const Date &Date::operator+=( int additionalDays )
78 { 1.8 endOfMonth
79 for ( int i = 0; i < additionalDays; i++ )
80 helpIncrement();
81
82 return *this; // enables cascading
83 }
84
85 // If the year is a leap year, return true;
86 // otherwise, return false
87 bool Date::leapYear( int y ) const
88 {
89 if ( y % 400 == 0 || ( y % 100 != 0 && y % 4 == 0 ) )
90 return true; // a leap year
91 else
92 return false; // not a leap year
93 }
94
95 // Determine if the day is the end of the month
96 bool Date::endOfMonth( int d ) const
 2000 Deitel97&{Associates, Inc. All rights
98 if ( month == 2 && leapYear( year ) )
99 return d == 29; // last day of Feb. in leap year Outline
100 else
101 return d == days[ month ];
102 } 1.9 helpIncrement
103
104 // Function to help increment the date
105 void Date::helpIncrement() 1.10 operator<<
106 {
107 if ( endOfMonth( day ) && month == 12 ) { // end year
(output Date)
108 day = 1;
109 month = 1;
110 ++year;
111 }
112 else if ( endOfMonth( day ) ) { // end month
113 day = 1;
114 ++month;
115 }
116 else // not end of month or year; increment day
117 ++day;
118 }
119
120 // Overloaded output operator
121 ostream &operator<<( ostream &output, const Date &d )
122 {
123 static char *monthName[ 13 ] = { "", "January",
124 "February", "March", "April", "May", "June",
125 "July", "August", "September", "October",
126 "November", "December" };
127
128 output << monthName[ d.month ] << ' '
129 << d.day << ", " << d.year;
130
131 return output; // enables cascading
 2000 Deitel & Associates, Inc. All rights
133 // Fig. 8.6: fig08_06.cpp
134 // Driver for class Date
135 #include <iostream>
Outline
136
137 using std::cout; 1. Load header
138 using std::endl;
139 d1 is January 1, 1900
140 #include "date1.h" d2 is December 27, 1992 1.1 Initialize objects
141
142 int main() d3 is January 1, 1900
143 { 2. Function calls
144 Date d1, d2( 12, 27, 1992 ), d3( 0, 99, 8045 );
145 cout << "d1 is " << d1
146 << "\nd2 is " << d2 3. Print results
147 << "\nd3 is " << d3 << "\n\n";
148
d2 += 7 is January 3, 1993
149 cout << "d2 += 7 is " << ( d2 += 7 ) << "\n\n";
150
151 d3.setDate( 2, 28, 1992 ); d3 is February 28, 1992
152 cout << " d3 is " << d3; ++d3 is February 29, 1992
153 cout << "\n++d3 is " << ++d3 << "\n\n";
154
Testing the preincrement operator:
155 Date d4( 3, 18, 1969 );
156 d4 is March 18, 1969
157 cout << "Testing the preincrement operator:\n" ++d4 is March 19, 1969
158 << " d4 is " << d4 << '\n';
159 cout << "++d4 is " << ++d4 << '\n'; d4 is March 19, 1969
160 cout << " d4 is " << d4 << "\n\n";
161
162 cout << "Testing the postincrement operator:\n" Testing the preincrement operator:
163 << " d4 is " << d4 << '\n'; d4 is March 18, 1969
164 cout << "d4++ is " << d4++ << '\n';
++d4 is March 19, 1969
165 cout << " d4 is " << d4 << endl;
166 d4 is March 19, 1969
167 return 0;
 2000 Deitel & Associates, Inc. All rights
d1 is January 1, 1900
d2 is December 27, 1992
d3 is January 1, 1900
Outline
d2 += 7 is January 3, 1993

d3 is February 28, 1992 Program Output


++d3 is February 29, 1992

Testing the preincrement operator:


d4 is March 18, 1969
++d4 is March 19, 1969
d4 is March 19, 1969

Testing the postincrement operator:


d4 is March 19, 1969
d4++ is March 19, 1969
d4 is March 20, 1969

 2000 Deitel & Associates, Inc. All rights

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy