#include<iostream>
using namespace std;
class Example {
public:
int set_func();
void get_func();
private:
int i;
};
int main()
{
Example ex;
cout << ex.set_func() << endl;
ex.get_func();
return 0;
}
int Example::set_func()
{
i = 10; // shorthand for this->i = 10;
return i; // shorthand for return this->i;
}
void Example::get_func()
{
cout << i << endl;
}
|
The purpose of operator overloading is to make programs clearer by using conventional meanings for existing operators, such as +, ==, [ ], etc. Operator overloading allows you to provide intuitive operators to user of your classes. They are "syntactic sugar" for function calls and do not add power to the language. For example, operator overloading would allow us to test the equality of arrays with == or != rather than with a function call. This makes your code more intuitive. Or you might want to increment a Time object timer with timer++.
In C++ operators can be overloaded relative to class types that you create. This allows you to integrate seamlessly new types and their operators into your programming environment. When you overload an operator, you define the meaning of an operator for a particular class. For example, a class that implements a stack might use the addition operator + to push an item onto a stack. Another class might use + in an entirely different way. When an operator is overloaded, none of its original meaning is lost. For example, if you overload the addition operator, addition of numeric values remains unchanged.
You can accomplish the same thing through a function, but operator overloading can make your code look cleaner and it may be easier to read. But, don't get carried away.
To overload an operator, you must define what the operation means relative to the class to which it is applied. To do this, you create an operator function. The general form is:
type classname::operator#(arg-list)
{
// code for operations
}
|
Substitute the operator you are overloading for the #. While type can be most any type, the return value is commonly of the same type as the class for which the operator is being overloaded. This correlation facilitates the use of the overloaded operator in compound expressions.
Operator functions can be either members or nonmembers of a class. Since nonmember operator functions are often friend functions, a concept we have not covered, we will restrict ourselves to member functions only. The program below in ThreeD.cpp creates a class called ThreeD, which maintains the coordinates of an object in 3-d space. It overloads the + and = operators relative to the ThreeD class.
// Define + and = for class ThreeD
#include<iostream>
using namespace std;
class ThreeD {
public:
ThreeD(); // default constructor
ThreeD(int i, int j, int k); // explicit constructor
~ThreeD() {} // destructor
ThreeD operator+ (ThreeD op2); // op1 is implied in prototype
ThreeD operator= (ThreeD op2); // op1 is implied in prototype
void show();
private:
int x, y, z; // 3-d coordinates
};
int main()
{
ThreeD a(1, 2, 3), b(10, 10, 10), c;
cout << "Original value of a: ";
a.show();
cout << "Original value of b: ";
b.show();
cout << "Original value of c: ";
c.show();
cout << endl;
c = a + b; // add a and b
cout << "Value of c after c = a + b: ";
c.show();
cout << endl;
c = b = a; // demonstrate multiple assignment
cout << "Value of a after c = b = a: ";
a.show();
cout << "Value of b after c = b = a: ";
b.show();
cout << "Value of c after c = b = a: ";
c.show();
return 0;
}
ThreeD::ThreeD() // default constructor
{
x = y = z = 0;
}
ThreeD::ThreeD(int i, int j, int k) // explicit constructor
{
if(i < 0 || j < 0 || k < 0) {
cout << "Negative coordinate - program terminated\n";
exit (1);
}
x = i;
y = j;
z = k;
}
// overload +
ThreeD ThreeD::operator+(ThreeD op2)
{
ThreeD temp;
// integer additions in the standard sense
temp.x = x + op2.x; // temp.x = this->x + op2.x;
temp.y = y + op2.y; // temp.y = this->y + op2.y;
temp.z = z + op2.z; // temp.z = this->z + op2.z;
return temp; // return the new object
}
// overload =
ThreeD ThreeD::operator=(ThreeD op2)
{
// integer assignments in the standard sense
x = op2.x; // this->x = op2.x;
y = op2.y; // this->y = op2.y;
z = op2.z; // this->z = op2.z;
// dereference the this pointer
// and return the modified object
return *this;
}
// show X, Y, and Z coordinates
void ThreeD::show()
{
cout << x << ", ";
cout << y << ", ";
cout << z << endl;
}
|
Original value of a: 1, 2, 3 Original value of b: 10, 10, 10 Original value of c: 0, 0, 0 Value of c after c = a + b: 11, 12, 13 Value of a after c = b = a: 1, 2, 3 Value of b after c = b = a: 1, 2, 3 Value of c after c = b = a: 1, 2, 3 |
Notice that both operator functions have only one parameter each, even though they overload binary operations. This is because when a binary operator is overloaded using a member function, only one argument is explicitly passed to it. The other argument is implicitly passed using the this pointer. Thus in the line
Remember, it is the operand on the left that invokes the operator function. The operand on the right is passed explicitly.
In general, when you use a member function, no parameters are used when overloading a unary operator, and only one parameter is required when overloading a binary operator. In either case, the object that invokes the operator function is implicitly passed via the this pointer.
Cautions:
It is also possible to overload unary operators. There are examples in your text.
Note: Much of this material is from an H. Schildt book.
Now let's look at another example. We will overload + to concatenate one string to another, and we will overload - to remove all instances of a character from a string.
Try this at home:   Overload  =  to copy one string into another.
#include <iostream>
#include <string>
using namespace std;
class String {
public:
String(char *); // constructor
void operator + (char *); // append a string
void operator - (char); // remove char from string
void show_string(); // display string
private:
char data[256];
};
int main()
{
String s1("CS 102 is similar to ECE 206; ");
char s2[] = "ECE 206 is similar to CS 102.";
String s3("");
s1 + s2;
s1.show_string();
s1 - '0';
s1.show_string();
}
String::String(char *str) // constructor
{
strcpy(data, str);
}
void String::operator + (char *str)
{
strcat(data, str);
}
void String::operator - (char letter)
{
char temp[256];
int i, j;
for(i = j = 0; data[i]; i++)
if(data[i] != letter) {
temp[j] = data[i]; // -OR- temp[j++] = data[i];
j++;
}
temp[j] = '\0'; // terminate string
strcpy(data, temp); // copy to data member
}
void String::show_string()
{
cout << data << endl;
}
|
CS 102 is similar to ECE 206; ECE 206 is similar to CS 102. CS 12 is similar to ECE 26; ECE 26 is similar to CS 12. |