1. Operators overloading
1.1. Example 1
In the class Array
implement the following operators:
-
+=
adding new elements in the array -
-=
deletes occurrences of the given integer argument -
<<
printing the elements of the array.
Test the class in a main function.
oop_av61a_en.cpp
#include <iostream>
using namespace std;
class Array {
private:
int *x;
int size;
int capacity;
public:
Array(const int capacity = 5) {
x = new int[capacity];
size = 0;
this->capacity = capacity;
}
// copy constructor
Array(const Array &a) {
size = a.size;
capacity = a.capacity;
x = new int[capacity];
for (int i = 0; i < size; ++i) {
x[i] = a.x[i];
}
}
// assignment operator =
Array& operator=(const Array &a) {
if (this == &a) return *this;
size = a.size;
capacity = a.capacity;
delete [] x;
x = new int[capacity];
for (int i = 0; i < size; ++i) {
x[i] = a.x[i];
}
return *this;
}
// destructor
~Array() {
delete [] x;
}
int getSize() {
return size;
}
int getCapacity() {
return capacity;
}
const int *getX() {
return x;
}
Array& operator+=(int n) {
if (capacity == size) {
int *y = new int[2 * capacity];
for (int i = 0; i < size; ++i) {
y[i] = x[i];
}
delete [] x;
x = y;
capacity = capacity * 2;
}
x[size] = n;
size++;
return *this;
}
Array& operator-=(int n) {
int newSize = 0;
for (int i = 0, j = 0; i < size; ++i)
if (x[i] != n) {
x[j++] = x[i];
newSize++;
}
size = newSize;
return *this;
}
//friend ostream & operator<<(ostream &o, Array &a);
};
ostream& operator<<(ostream &o, Array &a) {
for (int i = 0; i < a.getSize(); ++i) {
o << a.getX()[i] << " ";
}
for (int i = a.getSize(); i < a.getCapacity(); ++i) {
o << "- ";
}
o << endl;
return o;
}
int main() {
Array a;
a += 6;
a += 4;
a += 3;
a += 2;
a += 1;
Array b(a);
b -= 2;
b -= 3;
cout << " a: " << a;
cout << " b: " << b;
return 0;
}
1.2. Example 2
Extend the first example with overloading the following operators:
-
[]
for mutable access of element -
==
for comparison of two objects of classArray
.
Test the class in the main function.
oop_av61b_en.cpp
#include <iostream>
#include <cstdlib>
using namespace std;
class Array {
private:
int *x;
int size;
int capacity;
public:
Array(const int capacity = 5) {
x = new int[capacity];
size = 0;
this->capacity = capacity;
}
// copy constructor
Array(const Array &a) {
size = a.size;
capacity = a.capacity;
x = new int[capacity];
for (int i = 0; i < size; ++i) {
x[i] = a.x[i];
}
}
// assignment operator =
Array& operator=(const Array &a) {
if (this == &a) return *this;
size = a.size;
capacity = a.capacity;
delete [] x;
x = new int[capacity];
for (int i = 0; i < size; ++i) {
x[i] = a.x[i];
}
return *this;
}
// destructor
~Array() {
delete [] x;
}
int getSize() {
return size;
}
int getCapacity() {
return capacity;
}
const int *getX() {
return x;
}
Array & operator+= (int n) {
if (capacity == size) {
int *y = new int[2 * capacity];
for (int i = 0; i < size; ++i) {
y[i] = x[i];
}
delete [] x;
x = y;
capacity = capacity * 2;
}
x[size] = n;
size++;
return *this;
}
Array & operator-= (int n) {
int newSize = 0;
for (int i = 0, j = 0; i < size; ++i)
if (x[i] != n) {
x[j++] = x[i];
newSize++;
}
size = newSize;
return *this;
}
int& operator[](int index) {
int pom = -1;
if (index >= 0 && index < size )
return x [index];
else {
cout << " Out of range " << endl ;
exit(EXIT_FAILURE);
}
}
bool operator==(Array &a) {
if (this->size != a.size ) return false;
for (int i = 0; i < size; i++)
if (x[i] != a.x[i]) return false;
return true;
}
//friend ostream & operator<<(ostream &o, Array &a);
};
ostream& operator<<(ostream &o, Array &a) {
for (int i = 0; i < a.getSize(); ++i) {
o << a[i] << " "; // using the operator []
}
for (int i = a.getSize(); i < a.getCapacity(); ++i) {
o << "- ";
}
o << endl;
return o;
}
int main() {
Array a;
a += (6);
a += (4);
a += (3);
a += (2);
a += (1);
Array b(a);
b -= (2);
b -= (3);
a[0] = 9; // using the operator []
cout << " a: " << a;
cout << " b: " << b;
if (a == b) cout << "Equal";
else cout << "Not equal";
return 0;
}
2. Problems
2.1. Complex number
Define a class for complex numbers. For each complex number keep information for the real and for the imaginary part.
Overload the operators +, -, *, /, +=, -=, *=, /=
for executing the appropriate operations for complex numbers.
Implement the operator <<
for printing.
Also implement the operator +
for addition of complex number and real number and vice versa.
oop_av62_en.cpp
#include <iostream>
using namespace std;
class Complex {
private:
float real;
float imag;
public:
Complex(const float real = 0, const float imag = 0) {
this->real = real;
this->imag = imag;
}
Complex operator+(const Complex &c) {
return Complex(real + c.real, imag + c.imag);
}
friend Complex operator-(const Complex &c1, const Complex &c2); // as global function
Complex operator*(const Complex &c) {
return Complex(real * c.real - imag * c.imag, imag * c.real - real * c.imag);
}
Complex operator/(const Complex &c) {
float m = c.real * c.real + c.imag * c.imag;
float r = (real * c.real - imag * c.imag) / m;
return Complex(r, (real * c.real + imag * c.imag) / m);
}
Complex &operator+=(const Complex &c) {
real += c.real;
imag += c.imag;
return *this;
}
Complex &operator-=(const Complex &c) {
real -= c.real;
imag -= c.imag;
return *this;
}
Complex &operator*=(const Complex &c) {
real = real * c.real - imag * c.imag;
imag = imag * c.real - real * c.imag;
return *this;
}
Complex &operator/=(const Complex &c) {
*this = *this / c;
return *this;
}
bool operator==(const Complex &c) {
return real == c.real && imag == c.imag;
}
float getReal() const {
return real;
}
float getImag() const {
return imag;
}
Complex operator+(float n) {
return Complex(real + n, imag);
}
friend Complex operator+(float n, Complex &c);
friend ostream &operator<<(ostream &x, const Complex &c) {
x << c.real;
if (c.imag >= 0) {
x << "+";
}
x << c.imag << "j";
return x;
}
};
Complex operator-(const Complex &c1, const Complex &c2) {
return Complex(c1.real - c2.real, c1.imag - c2.imag);
}
Complex operator+(float n, Complex &c) {
return Complex(c.real + n, c.imag);
}
int main() {
Complex c1(2, -6);
Complex c2(3, 5);
Complex c = c1 + c2;
cout << c1 << " + " << c2 << " = " << c << endl;
c = c1 - c2;
cout << c1 << " - " << c2 << " = " << c << endl;
c = c1 * c2;
cout << c1 << " * " << c2 << " = " << c << endl;
c = c1 / c2;
cout << c1 << " / " << c2 << " = " << c << endl;
if (c == c1) {
cout << "Numbers are equal" << endl;
}
c = c1 + 2;
cout << c1 << " + " << 2 << " = " << c << endl;
c = 2 + c1;
cout << 2 << " + " << c1 << " = " << c << endl;
return 0;
}
2.2. Students
Implement a class for students. Each student has a name (dynamically allocated char array), average (real number) and academic year (integer). Implement the following:
-
Constructors and destructor
-
operator
++
that will increment the academic year for +1 -
operator
<<
for printing a student with all the information -
operator
>
for comparing two students by their average.
Then implement a class for a group of students that keeps dynamically allocated array of students and their number. For this class implement:
-
Constructors and destructor
-
operator
+=
for adding new student in the group -
operator
++
for increasing the school year for +1 -
operator
<<
for printing all the students in the group -
method
reward
that print only students that have an average higher than 9.0. -
method
highestAverage
that will print the highest average of the group.
oop_av63_en.cpp
#include <iostream>
#include <string.h>
#define MAX 100
using namespace std;
class Student
{
private:
char *name;
float average;
int academicYear;
public:
Student(const char* n = "", float a = 0, int ay = 0) {
name = new char[strlen(n) + 1];
strcpy(name, n);
average = a;
academicYear = ay;
}
Student(const Student& u) {
name = new char[strlen(u.name) ];
strcpy(name , u.name);
average = u.average;
academicYear = u.academicYear;
}
~Student() {
delete [] name;
}
Student& operator=(const Student& u) {
if (this != &u) {
delete [] name;
name = new char[strlen(u.name)];
strcpy(name, u.name);
average = u.average;
academicYear = u.academicYear;
}
return *this;
}
Student& operator++() { // prefix operator
academicYear++;
return *this;
}
Student operator++(int) { // postfix
Student u(*this);
academicYear++;
return u;
}
float getAverage() {
return average;
}
friend ostream& operator<<(ostream& o, const Student& u) {
return o << "Name: " << u.name << ", academicYear: " << u.academicYear << ", average: " << u.average << endl;
}
friend bool operator>(const Student& s1, const Student& s2);
};
bool operator>(const Student& s1, const Student& s2) {
return s1.average > s2.average;
}
class Group
{
private:
Student* students;
int count;
void copy(const Group &g) {
this -> count = g.count;
this -> students = new Student[count];
for (int i = 0; i < count; i ++)
students[i] = g.students[i];
}
public:
Group(Student* s = 0, int c = 0) {
count = c;
students = new Student [count];
for (int i = 0; i < count; i ++)
students[i] = s[i];
}
Group(const Group &g) {
copy(g);
}
~Group() {
delete [] students;
}
Group& operator+=(Student s) {
Student* tmp = new Student[count + 1];
for (int i = 0; i < count; i++)
tmp[i] = students[i];
tmp [count ++] = s;
delete [] students;
students = tmp;
return *this;
}
Group& operator++() {
for (int i = 0; i < count; i++)
students[i]++;
return *this;
}
Group operator++(int) {
Group g(*this);
for (int i = 0; i < count; i++)
students[i]++;
return g;
}
friend ostream& operator<<(ostream& o, const Group& p) {
for (int i = 0; i < p.count; i ++)
o << p.students[i];
return o;
}
void reward() {
for (int i = 0; i < count; i++)
if (students[i].getAverage() > 9.0)
cout << students[i];
}
void highestAverage() {
Student tmpU = students[0];
for (int i = 0; i < count; i++)
if (students[i] > tmpU)
tmpU = students[i];
cout << "Highest average in the group:" << tmpU.getAverage() << endl;
}
};
int main() {
Student s1("Martina Martinovska", 9.5, 3);
Student s2("Darko Darkoski", 7.3, 2);
Student s3("Angela Angelovska", 10, 3);
Group group;
group += s1;
group += s2;
group += s3;
cout << group;
cout << "Reward:" << endl;
group.reward();
cout << endl;
group.highestAverage();
cout << endl;
s2++;
cout << group;
cout << endl;
group++;
cout << group;
return 0;
}