You are on page 1of 26

Зміст

Завдання...........................................................................................................................3
Вступ................................................................................................................................4
Діаграми класів...............................................................................................................6
Опис програми................................................................................................................8
Інструкція користувача..................................................................................................9
Контрольний приклад...................................................................................................10
Висновок........................................................................................................................11
Література......................................................................................................................12
Додаток А

2
Завдання

1. Створіть клас РЯДОК СИМВОЛІВ з полями даних: вказівник на початок рядка


у динамічній пам’яті, довжина рядка.
2. Визначити конструктори ініціалізації, копіювання, деструктори та методи для
встановлення та отримання значень полів цього класу.
3. Перевантажити операцію + для конкатенації рядків, - витирання підрядка з
рядка, * перевірки входження підрядка у рядок, операцію присвоєння об’єктів
=, потокові операції введення та виведення об’єктів.
4. Визначити похідний клас ВЕЛИКІ ЦІЛІ ЧИСЛА, які не можуть бути зображені
значеннями вбудованих типів. Визначити операторні методи введення,
виведення, виконання арифметичних операцій та порівняння великих чисел.
5. У межах ієрархії класів побудувати поліморфічний кластер на основі
віртуального операторного методу +.
6. Розробити клас МАСИВ ВЕЛИКИХ ЧИСЕЛ, який складається з об’єктів класу
ВЕЛИКІ ЧИСЛА. Знайти суму елементів масиву.
7. Для роботи з масивом об’єктів побудувати та використати клас-ітератор.

3
Вступ

Об’єктно-орієнтоване програмування (ООП) – це еволюційний крок, який


випливає із розвитку програмування. ООП дає нам можливість відчути себе не
тільки програмістом, а й архітектором, проектуючи структуру програми,
створюючи красиві форми. Створення класів за допомогою ООП можна порівняти
з будуванням будинку. Спочатку ми створюємо план – описуємо клас, а пізніше
будуємо будинок – створюємо об’єкт, тобто сутність класу.
З розвитком програмування виникла ідея поєднати в межах однієї сутності
дані і код, що безпосередньо опрацьовує ці дані. Така сутність отримала назву
об’єкт, а відповідний підхід до створення програм називають об’єктно-
орієнтованим програмуванням.
Об’єктно-орієнтоване програмування (ООП) – це парадигма програмування,
яка розглядає програму як сукупність гнучко пов’язаних між собою об’єктів.
Кожен об’єкт має суттєві характеристики, які відрізняють його від усіх інших
об’єктів. Сукупність таких характеристик називається абстракцією. Розрізняють
абстракції стану та поведінки об’єкта.
Стан (дані об’єкта) характеризується переліком та значенням певних ознак.
Поведінка (функціонал об’єкта) визначається набором операцій, які виконуються
об’єктом, або над об’єктом.
Кожен об’єкт є екземпляром (представником) певного класу. Відповідно, клас
– це відповідна абстракція об’єктів.
Інкапсуляція – це механізм в програмуванні, який пов’язує в одне ціле
функції і дані, якими вони маніпулюють, а також захищає їх від зовнішнього
доступу і неправильного застосування. В об’єктно-орієнтованій мові функції і всі
необхідні дані можуть пов’язуватись таким способом, що створюється автономна
структура – об’єкт. Іншими словами, об’єктом є структура, яка підтримує
інкапсуляцію. В межах об’єкта функції, дані або і функції і дані можуть бути або
закритими для інших об’єктів (private), або відкритими (public).
Успадкування – це властивість, з допомогою якої один об’єкт може набувати

4
властивостей іншого. При цьому підтримується концепція ієрархічної
класифікації. Без використання успадкування кожний об’єкт повинен явно
визначати всі свої характеристики; використовуючи наслідування, об’єкт повинен
визначати тільки ті якості, які роблять його унікальним в межах свого класу.
Визначення нового класу може базуватись на визначенні вже існуючого. В такому
випадку, новий клас отримає властивості та поведінку базового класу, та
доповнить їх своїми власними. У випадку одиничного успадкування, у кожного
класу може бути лише один безпосередній базовий клас. У випадку множинного
успадкування, дозволяється існування декількох безпосередніх надкласів.
Застосування методів успадкування дозволяє покращити повторне використання
коду шляхом використання вже визначених властивостей та методів (поведінки)
базових класів.
Разом з інкапсуляцією і успадкуванням поліморфізм також являє собою одну
із важливих концепцій ООП. Застосування цієї концепції дозволяє значно
полегшити розробку складних програм.
Термін поліморфізм має грецьке походження і означає «наявність багатьох
форм». З поліморфізмом тісно пов’язані такі поняття, як абстрактні класи,
віртуальні методи, перевантаження методів і властивостей.

5
Діаграми класів

Для даного завдання було створено чотири класи. Даний розділ розглядає
будову кожного класу, а також вказує зв’язки між ними.

Основу програми створює ієрархія з двох класів String та Number. Базовий


клас представляє собою стрічку, яка може зберігати будь-яку текстову
інформацію, коли похідний клас дозволяє зберігати лише цифри.
Базовий клас містить два поля: вказівник на рядок і його розмір. Методи
класу включають в себе перевантажені оператори, які налаштовані для роботи зі
стрічками, а також метод який дає доступ до закритого поля з довжиною стрічки.
Похідний клас не містить своїх унікальних полів, оскільки для його
функціонування цілком достатньо полів які він отримав при успадкуванні. Однак
методи класу перевантажені для роботи з числами, а не з текстовою інформацією.

6
Array – клас-контейнер, який містить масив об’єктів Number. Він містить два
поля: вказівник на початок масиву і його статичний розмір. Розмір масиву
задається при створенні екземпляру даного класу і не може змінюватись. Для того
щоб запобігти виникненню помилок пов’язаних з виходом за межі масиву,
перевантажений оператор [] перевіряє коректність індекса.

Для роботи з класом-контейнером було створено клас-ітератор. Він містить


відповідні вказівники, які даватимуть доступ до контейнера. Для коректної роботи
перевантажені базову оператори, які використовуються при адресній арифметиці.

7
Опис програми

Дана програма дозволяє зберігати числа, які є настільки великими, що


вбудовані типи не справляються з ними. Щоб це реалізувати числа
представляються у вигляді стрічки. Це дозволяє нам розглядати величину числа
не за його значенням, а за його довжиною, іншими словами – кількістю цифр.
Для того щоб показати числа у "повній красі" дана програма може
реалізовувати арифметичні дії над стрічковими числами.
Базовими операціями є звісно ж додавання та віднімання. Алгоритм цих дій
полягає у розгляді числа посимвольно, тобто по одній цифрі, і реалізація
звичайного додавання/віднімання у стовпчик.
Більш складнішими операціями є множення та ділення, та в їх основі лежать
базові операції. Множення – це не що інше як додавання одного і того самого
числа N раз, а ділення – це кількість ітерацій віднімання дільника від діленого до
отримання 0 (або ж значення меншого за дільник, тоді це число буде остачею).
Недоліком програми є відсутність роботи з від’ємними числами. Так при
результаті меншим за 0 буде виведено 0 або ж вхідне число.
Для перевірки коректності роботи програми перевіряються усі вхідні дані, а
також виключні ситуації при кожній операції, яка може завершитися невдачею
(наприклад: виділення динамічної пам’яті). Якщо виникла помилка програма
виведе відповідне повідомлення на екран. У деяких випадках при відсутній
можливості відновити коректну роботу програми, врна аварійно завершиться.

8
Інструкція користувача

При запуску програми користувачу запропоновано ввести 5 чисел. Після


введення інформації буде обраховано суму даних чисел і результат виведеться на
екран.

9
Контрольний приклад

Оскільки основою програми є класи String та Number перевіримо результати


виконання різних операцій над екземплярами даних класів.
Для цього створимо два тестових модуля які дозволяють ввести інформацію
для ініціалізації двох об’єктів і викликають усі методи в яких можливе
виникнення помилки.
Тестування об’єктів класу String:

Тестування об’єктів класу Number:

З даних тестів видно, що всі операції виконуються правильно.

10
Висновок

Виконуючи завдання розрахункової роботи, я покращив свої знання в області


об’єктно-орієнтованого програмування. Навчився опрацьовувати виключні
ситуації та таким чином передбачати та відлагоджувати некоректне виконання
програми. Покращив свої навички написання коду та роботи зі стрічками. Освоїв
такі поняття як класи-контейнери та класи-ітератори.

11
Література

1. Bjarne Stroustrup. The C++ Programming Language Third Edition, 1997


2. Герберт Шилдт. Полный справочник по C++, 2006
3. Сэджвик Р. Фундаментальные алгоритмы на С++. Части 1-4, 2001

12
Додаток А

String.h
/* Цей клас працює за допомогою вказівника char, створюючи зручний для користувача
тип рядка */
#pragma once

#include <cstring>
#include <cctype>
#include <cstdlib>
#include <iostream>

using namespace std;

class String
{
protected:
char* str;
unsigned length;

public:
// конструктори і деструктор
String(void);
String(char*);
String(const String&);
virtual ~String(void);
unsigned getlen(); // отримати довжину рядка
// перевантаження основного оператора
String& operator = (const String&); // призначити об'єкт класу
String& operator = (const char*); // призначити константний
літерал
virtual String operator + (String&); // конкат з об'єктом класу
String operator + (const char*); // конкат з константним
літералом
String operator - (const char*); // видалити підрядок
bool operator * (const char*); // перевірка наявного
підрядка
friend ostream& operator << (ostream&, String&); // вихідний потік
friend istream& operator >> (istream&, String&); // вхідний потік
};

String.cpp
#include "String.h"

String::String(void)
{
str = NULL;
length = 0;
}

String::String(char* str)
{
unsigned size = strlen(str) + 1;

try { this->str = new char [size]; }


catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}
memcpy(this->str, str, size);
this->length = size-1;
}

String::String(const String& copy)


{
try { this->str = new char [copy.length + 1]; }
catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}

memcpy(this->str, copy.str, copy.length + 1);


this->length = copy.length;
}

String::~String(void)
{
if (str)
{
delete[] str;
str = NULL;
}
}

unsigned String::getlen()
{
return this->length;
}

String& String::operator = (const String& s)


{
// check for self assigment
if (this == &s)
return *this;

try { this->str = new char [s.length + 1]; }


catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}

memcpy(this->str, s.str, s.length + 1);


this->length = s.length;

return *this;
}

String& String::operator = (const char* s)


{
unsigned size = strlen(s) + 1;

try { this->str = new char [size]; }


catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}

memcpy(this->str, s, size);
this->length = size - 1;
return *this;
}

String String::operator + (String& s)


{
if (s.str == NULL)
return *this;

unsigned size = this->length + s.length + 2;


String tmp;

try { tmp.str = new char [size]; }


catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}

tmp.length = size - 2;

if (this->str)
{
strcpy(tmp.str, this->str);
strcat(tmp.str, s.str);
}

else
strcpy(tmp.str, s.str);

return tmp;
}

String String::operator + (const char* s)


{
if (s == NULL)
return *this;

unsigned size = this->length + strlen(s) + 2;


String tmp;

try { tmp.str = new char [size]; }


catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}

tmp.length = size - 2;

if (this->str)
{
strcpy(tmp.str, this->str);
strcat(tmp.str, s);
}

else
strcpy(tmp.str, s);

return tmp;
}

String String::operator - (const char* s)


{
unsigned len1 = strlen(s);
if (len1 == 0) // check if string is not empty
return *this;

while(1) // repeat until all substrings are deleted


{
char* ptr = strstr(this->str, s); // find next substring
if (ptr == NULL)
break;

unsigned len2 = strlen(ptr);


unsigned size = this->length - len1 + 1;
char* tmp;

*ptr = '\0'; // mark the begining of the substring

try { tmp = new char [size]; }


catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}

// copy string without the substring


memcpy(tmp, this->str, this->length - len2 + 1);
strcat(tmp, ptr+len1);

delete[] this->str;

try { this->str = new char [size]; }


catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}

memcpy(this->str, tmp, size);


delete[] tmp;
}

return *this;
}

bool String::operator * (const char* s)


{
char* ptr = strstr(this->str, s);
if (ptr == NULL)
return false;
else
return true;
}

ostream& operator << (ostream& stream, String& s)


{
if (s.str == NULL)
{
stream << "Error: Nothing to output";
stream << endl;
return stream;
}

stream << s.str;


stream << endl;
return stream;
}
istream& operator >> (istream& stream, String& s)
{
char buf[256];

stream.getline(buf, sizeof(buf));

unsigned size = strlen(buf) + 1;

try { s.str = new char [size]; }


catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}

memcpy(s.str, buf, size);


s.length = size - 1;

return stream;
}

Number.h
/* This class represents a long number which is
represented as a string which gives the ability
to store numbers greater than any built-in type */

#pragma once

#include "String.h"

class Number : public String


{
private:
void balance(); // dispose of insignificant zeroes

public:
// constructors and destructor
Number(void);
Number(char*);
Number(const Number&);
~Number(void);

// basic operator overloading


Number operator + (Number&); // add long numbers
Number operator - (Number&); // subtract long numbers
Number operator * (int); // multiply long numbers
int operator / (Number&); // divide long numbers
friend bool operator == (Number&, Number&); // check if equal
friend bool operator != (Number&, Number&); // check if not equal
friend bool operator > (Number&, Number&); // check if greater
friend bool operator < (Number&, Number&); // check if lesser
friend bool operator >= (Number&, Number&); // check if greater equal
friend bool operator <= (Number&, Number&); // check if lesser equal
friend istream& operator >> (istream&, Number&); // input stream
};

Number.cpp
#include "Number.h"

Number::Number(void){}

Number::Number(char* str) : String(str) {}

Number::Number(const Number& copy) : String(copy) {}

Number::~Number(void){}

void Number::balance()
{
// find out if there are insignificant symbols
if ((str[0] <= '0' || str[0] > '9') && length > 1)
{
int i;
for (i = 1; i < length-1; i++) // find where they end
if (str[i] != '0')
break;

char tmp[256];
memcpy(tmp, str+i, length+1-i);

delete[] str;

length = strlen(tmp);
str = new char[length+1];

memcpy(str, tmp, length+1);


}
}

Number Number::operator + (Number& n)


{
if (n.str == NULL)
return *this;

unsigned size = this->length + n.length + 2;


Number tmp;

try { tmp.str = new char [size]; }


catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}

int rem = 0; // remainder from overflow


int i = this->length-1; // first number index
int j = n.length-1; // second number index
int k = 0; // result number index

while (i >= 0 || j >= 0)


{
if (i < 0)
tmp.str[k] = (n.str[j] - '0') + rem;
else if (j < 0)
tmp.str[k] = (this->str[i] - '0') + rem;
else
tmp.str[k] = (this->str[i] - '0') + (n.str[j] - '0') + rem;

rem = tmp.str[k] / 10; // calculate remainder

if (tmp.str[k] > 9)
tmp.str[k] = (tmp.str[k] % 10);

tmp.str[k] += '0'; // change back to ASCII


k++;
i--;
j--;
}

// if remainder if full add


if (rem != 0)
{
tmp.str[k] = rem + '0';
k++;
}

tmp.str[k] = '\0';
tmp.length = k;

// reverse string
for (int q = 0; q < (tmp.length)/2; q++)
{
tmp.str[q] += tmp.str[tmp.length-1-q];
tmp.str[tmp.length-1-q] = tmp.str[q] - tmp.str[tmp.length-1-q];
tmp.str[q] -= tmp.str[tmp.length-1-q];
}

tmp.balance();
return tmp;
}

Number Number::operator - (Number& n)


{
if (n.str == NULL)
return *this;

if (*this < n)
return "0";

unsigned size = this->length + n.length + 2;


Number tmp;

try { tmp.str = new char [size]; }


catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}

int i = this->length-1; // first number index


int j = n.length-1; // second number index
int k = 0; // result number index

while (i >= 0 || j >= 0)


{
if (i < 0)
tmp.str[k] = (n.str[j] - '0');

else if (j < 0)
{
// check if need to borrow
if (this->str[i] < '0' || this->str[i] < n.str[j])
{
this->str[i] += 10;
this->str[i-1] -= 1;
}

tmp.str[k] = (this->str[i] - '0');


}

else
{
// check if need to borrow
if (this->str[i] < '0' || this->str[i] < n.str[j])
{
this->str[i] += 10;
this->str[i-1] -= 1;
}

tmp.str[k] = (this->str[i] - '0') - (n.str[j] - '0');


}

tmp.str[k] += '0'; // change back to ASCII


k++;
i--;
j--;
}

tmp.str[k] = '\0';
tmp.length = k;

// reverse string
for (int q = 0; q < (tmp.length)/2; q++)
{
tmp.str[q] += tmp.str[tmp.length-1-q];
tmp.str[tmp.length-1-q] = tmp.str[q] - tmp.str[tmp.length-1-q];
tmp.str[q] -= tmp.str[tmp.length-1-q];
}

tmp.balance();
return tmp;
}

Number Number::operator * (int x)


{
Number tmp;

if (x == 0)
return (*this - *this);

if (x < 0)
return *this;

// adding N times is equal to multiplying by N


for (int i = 0; i < x; i++)
tmp = tmp + *this;

return tmp;
}

int Number::operator / (Number& x)


{
int res = 0;
Number check = *this;
Number ZERO("0");

if (x == ZERO)
{
cout << "Error: Division by zero!" << endl;
getchar();
exit(-1);
}

// division is equal to iteration count


while (check >= x)
{
check = check - x;
res++;
}

return res;
}

bool operator == (Number& n1, Number& n2)


{
n1.balance();
n2.balance();

if (n1.length != n2.length)
return false;

for (int i = 0; i < n1.length; i++)


if (n1.str[i] == n2.str[i])
continue;
else
return false;

return true;
}

bool operator != (Number& n1, Number& n2)


{
return !(n1 == n2);
}

bool operator > (Number& n1, Number& n2)


{
n1.balance();
n2.balance();

if (n1.length > n2.length)


return true;

if (n1.length < n2.length)


return false;

for (int i = 0; i < n1.length; i++)


if (n1.str[i] > n2.str[i])
return true;
else if (n1.str[i] == n2.str[i])
continue;
else
return false;

return false;
}

bool operator < (Number& n1, Number& n2)


{
n1.balance();
n2.balance();

if (n1.length < n2.length)


return true;

if (n1.length > n2.length)


return false;

for (int i = 0; i < n1.length; i++)


if (n1.str[i] < n2.str[i])
return true;
else if (n1.str[i] == n2.str[i])
continue;
else
return false;

return false;
}

bool operator >= (Number& n1, Number& n2)


{
return n1 > n2 || n1 == n2;
}

bool operator <= (Number& n1, Number& n2)


{
return n1 < n2 || n1 == n2;
}

istream& operator >> (istream& stream, Number& n)


{
char buf[256];

stream.getline(buf, sizeof(buf));

unsigned size = strlen(buf) + 1;

for (int i = 0; i < size-1; i++)


if (!isdigit(buf[i]))
{
stream.clear();
cout << "Error: Characters detected";
cout << endl;
return stream;
}

try { n.str = new char [size]; }


catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}

memcpy(n.str, buf, size);


n.length = size - 1;

n.balance();
return stream;
}

Array.h
/* This class represents an array of objects
of type Number whith a field that holds the
coresponding size of the array */
#pragma once

#include "Number.h"
#include <cstring>

class Array
{
private:
Number* arr; // pointer to array

public:
unsigned size; // array size

// constructors and destructor


Array(void);
Array(unsigned);
Array(const Array&);
~Array(void);

Number count(Number*, Number*); // count sum in defined interval

Array& operator = (const Array&); // assigment operator


Number& operator [](int); // access operator

friend class Iterator;


};

Array.cpp
#include "Array.h"

Array::Array(void)
{
this->size = 1;

try { this->arr = new Number [this->size]; }


catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}
}

Array::Array(unsigned size)
{
this->size = size;

try { this->arr = new Number [this->size]; }


catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}
}

Array::Array(const Array& copy)


{
try { this->arr = new Number [copy.size]; }
catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}
memcpy(this->arr, copy.arr, sizeof(copy.arr));
this->size = copy.size;
}

Array::~Array(void)
{
if (arr)
{
delete[] arr;
arr = NULL;
}
}

Array& Array::operator = (const Array& a)


{
// check for self assigment
if (this == &a)
return *this;

try { this->arr = new Number [a.size]; }


catch(bad_alloc)
{
cout << "Error: Could not allocate
memory!"; exit(-1);
}

memcpy(this->arr, a.arr, sizeof(a.arr));


this->size = a.size;

return *this;
}

Number& Array::operator [](int i)


{
// check if allowed index
if (i < 0 || i >= size)
{
static Number err("Error: Out of scope");
return err;
}

return arr[i];
}

Number Array::count(Number* start, Number* end)


{
Number res("0");

while (start != end)


{
res = res + *start;
start++;
}

return (res + *end);


}

Iterator.h
/* This class represent an iterator which
will go through the Array container */
#pragma once

#include "Number.h"
#include "Array.h"
#include <iostream>
#include <cstring>

class Iterator
{
//private:
private:
Array* iter; // pointer to container
Number* ptr_begin; // pointer to beginning
Number* ptr_end; // pointer to end
Number* ptr_cur; // pointer to current
public:
Iterator(void);
explicit Iterator(Array&);
Iterator(const Iterator&);
~Iterator(void);

Number* begin(); // get pointer to first element


Number* end(); // get pointer to last element
Number* cur(); // get pointer to current element

// iterator operator overloading


Iterator& operator = (Array&);
Iterator& operator = (const Iterator&);
Number& operator * () const;
void operator ++ ();
void operator -- ();
void operator ++ (int);
void operator -- (int);
void operator + (int);
void operator - (int);
};

Iterator.cpp
#include "Iterator.h"

Iterator::Iterator(void)
{
this->iter = NULL;
this->ptr_begin = NULL;
this->ptr_end = NULL;
this->ptr_cur = NULL;
}

Iterator::Iterator(Array& a)
{
this->iter = &a;
this->ptr_begin = a.arr;
this->ptr_end = a.arr + a.size - 1;
this->ptr_cur = a.arr;
}

Iterator::Iterator(const Iterator& copy)


{
this->iter = copy.iter;
this->ptr_begin = copy.ptr_begin;
this->ptr_end = copy.ptr_end - 1;
this->ptr_cur = copy.ptr_cur;
}

Iterator::~Iterator(void)
{
if (iter)
{
delete iter;
delete ptr_begin;
delete ptr_end;
delete ptr_cur;
iter = NULL;
ptr_begin = NULL;
ptr_end = NULL;
ptr_cur = NULL;
}
}

Number* Iterator::begin()
{
return ptr_begin;
}

Number* Iterator::end()
{
return ptr_end;
}

Number* Iterator::cur()
{
return ptr_cur;
}

Iterator& Iterator::operator = (Array& a)


{
if (this->iter == &a)
return *this;

this->iter = &a;
this->ptr_begin = a.arr;
this->ptr_end = a.arr + a.size - 1;
this->ptr_cur = a.arr;
return *this;
}

Iterator& Iterator::operator = (const Iterator& i)


{
if (this == &i)
return *this;

this->iter = i.iter;
this->ptr_begin = i.ptr_begin;
this->ptr_end = i.ptr_end;
this->ptr_cur = i.ptr_cur;
return *this;
}

Number& Iterator::operator * () const


{
return *ptr_cur;
}

void Iterator::operator ++ ()
{
if (ptr_cur == ptr_end)
return;
ptr_cur++;
}

void Iterator::operator -- ()
{
if (ptr_cur == ptr_begin)
return;
ptr_cur--;
}

void Iterator::operator ++ (int)


{
if (ptr_cur == ptr_end)
return;
ptr_cur++;
}

void Iterator::operator -- (int)


{
if (ptr_cur == ptr_begin)
return;
ptr_cur--;
}

void Iterator::operator + (int n)


{
ptr_cur += n;
}

void Iterator::operator - (int n)


{
ptr_cur -= n;
}

main.cpp
#include <iostream>
#include "Number.h"
#include "Array.h"
#include "Iterator.h"

using namespace std;

int main()
{
Array a(5);
Number num;
Iterator iter;

cout << "Input 5 numbers: " << endl;


for (int i=0; i<5; i++)
{
cin >> num;
a[i] = num;
}

iter = a;

cout << "\n\nSum of all numbers = ";


cout << a.count(iter.begin(), iter.end());
return 0;
}

You might also like