Читайте также:
|
|
Для закрепления пройденного материала по теме «Перегрузка опреаций» разберите со студентами полные варианты классов «Дробь» и «Вектор».
Окончательный вариант класса «Дробь».
Заголовочный файл:
#ifndef __DROB_H__ #define __DROB_H__ class Drob { private: int ch; int zn; public: // Конструктор Drob(int ach = 0, int azn = 1); // Служебные методы void Clear() { ch = 0; zn = 1; } void Set(int ach, int azn); int GetCh() const { return ch; } int GetZn() const { return zn; } // Преобразование дроби int GetInt() const { return ch / zn; } double GetDecimal() const { return (double)ch / zn; } // Перегруженные операции преобразования типов operator int() const { return GetInt(); } operator double() const { return GetDecimal(); } // Перегруженная операция присваивания для целого Drob& operator=(int n); // Перегруженные операции инкремента/декремента Drob& operator++(); Drob& operator--(); Drob operator++(int); Drob operator--(int); // Перегруженная операция () void operator()(int ach, int azn); // Перегруженные операции выделения и // освобождения динамической памяти void* operator new(size_t size); void* operator new[](size_t size); void operator delete(void *p); void operator delete[](void *p); // Перегруженные сокращенные арифметические операции // для двух дробей и для дроби и целого числа Drob& operator+=(const Drob& d); Drob& operator-=(const Drob& d); Drob& operator*=(const Drob& d); Drob& operator/=(const Drob& d); Drob& operator+=(int n); Drob& operator-=(int n); Drob& operator*=(int n); Drob& operator/=(int n); // Друзья класса friend Drob operator+(const Drob& d1, const Drob& d2); friend Drob operator-(const Drob& d1, const Drob& d2); friend Drob operator*(const Drob& d1, const Drob& d2); friend Drob operator/(const Drob& d1, const Drob& d2); friend Drob operator+(const Drob& d, int n); friend Drob operator-(const Drob& d, int n); friend Drob operator*(const Drob& d, int n); friend Drob operator/(const Drob& d, int n); friend Drob operator+(int n, const Drob& d); friend Drob operator-(int n, const Drob& d); friend Drob operator*(int n, const Drob& d); friend Drob operator/(int n, const Drob& d); // Перегруженные потоковые операции ввода и ввывода friend ostream& operator<<(ostream& os, const Drob& c); friend istream& operator>>(istream& is, Drob& c); }; // // Внешняя перегрузка операций (друзья класса) // inline Drob operator+(const Drob& d1, const Drob& d2) { return Drob(d1.ch * d2.zn + d2.ch * d1.zn, d1.zn * d2.zn); } inline Drob operator-(const Drob& d1, const Drob& d2) { return Drob(d1.ch * d2.zn - d2.ch * d1.zn, d1.zn * d2.zn); } inline Drob operator*(const Drob& d1, const Drob& d2) { return Drob(d1.ch * d2.ch, d1.zn * d2.zn); } inline Drob operator/(const Drob& d1, const Drob& d2) { return Drob(d1.ch * d2.zn, d1.zn * d2.ch); } inline Drob operator+(const Drob& d, int n) { return Drob(d.ch + n * d.zn, d.zn); } inline Drob operator-(const Drob& d, int n) { return Drob(d.ch - n * d.zn, d.zn); } inline Drob operator*(const Drob& d, int n) { return Drob(d.ch * n, d.zn); } inline Drob operator/(const Drob& d, int n) { return Drob(d.ch, d.zn * n); } inline Drob operator+(int n, const Drob& d) { return Drob(d.ch + n * d.zn, d.zn); } inline Drob operator-(int n, const Drob& d) { return Drob(d.ch - n * d.zn, d.zn); } inline Drob operator*(int n, const Drob& d) { return Drob(d.ch * n, d.zn); } inline Drob operator/(int n, const Drob& d) { return Drob(d.ch, d.zn * n); } // // Внешняя перегрузка операций // inline bool operator!(const Drob& d) { return d.GetDecimal() == 0; } inline bool operator<(const Drob& d1, const Drob& d2) { return d1.GetDecimal() < d2.GetDecimal(); } inline bool operator>(const Drob& d1, const Drob& d2) { return d1.GetDecimal() > d2.GetDecimal(); } inline bool operator<=(const Drob& d1, const Drob& d2) { return d1.GetDecimal() <= d2.GetDecimal(); } inline bool operator>=(const Drob& d1, const Drob& d2) { return d1.GetDecimal() >= d2.GetDecimal(); } inline bool operator==(const Drob& d1, const Drob& d2) { return d1.GetDecimal() == d2.GetDecimal(); } inline bool operator!=(const Drob& d1, const Drob& d2) { return d1.GetDecimal()!= d2.GetDecimal(); } #endif/* __DROB_H__ */ |
Файл с исходным кодом:
#include <stdlib.h> // malloc, free #include <memory.h> // memset #include <iostream.h> #include "Drob.h" // // Методы класса Drob // // Конструктор Drob::Drob(int ach/* = 0 */, int azn/* = 1 */) { if (!azn) { ch = 0; zn = 1; } else { ch = ach; zn = azn; } } // Setter void Drob::Set(int ach, int azn) { if (azn) { ch = ach; zn = azn; } } // Перегруженная операция присваивания для целого Drob& Drob::operator=(int n) { ch = n; zn = 1; return *this; } // // Перегруженные операции инкремента/декремента // Drob& Drob::operator++() { // Изменяем, а затем возвращаем себя ch += zn; return *this; } Drob& Drob::operator--() { // Изменяем, а затем возвращаем себя ch -= zn; return *this; } Drob Drob::operator++(int) { // Делаем копию себя Drob tmp = *this; // Изменяем себя ch += zn; // Возвращаем копию себя до изменения return tmp; } Drob Drob::operator--(int) { // Делаем копию себя Drob tmp = *this; // Изменяем себя ch -= zn; // Возвращаем копию себя до изменения return tmp; } // Перегруженная операция () void Drob::operator()(int ach, int azn) { Set(ach, azn); } // // Перегруженные операции выделения и освобождения динамической памяти // // Выделяет память и заполняет ее нулями void* Drob::operator new(size_t size) { void *p = malloc(size); memset(p, 0, size); return p; } // Выделяет память и заполняет ее нулями void* Drob::operator new[](size_t size) { void *p = malloc(size); memset(p, 0, size); return p; } // Освобождает выделенную в new память void Drob::operator delete(void *p) { free(p); } // Освобождает выделенную в new[] память void Drob::operator delete[](void *p) { free(p); } // // Перегруженные сокращенные арифметические операции // для двух дробей и для дроби и целого числа // Drob& Drob::operator+=(const Drob& d) { ch = ch * d.zn + d.ch * zn; zn *= d.zn; return *this; } Drob& Drob::operator-=(const Drob& d) { ch = ch * d.zn - d.ch * zn; zn *= d.zn; return *this; } Drob& Drob::operator*=(const Drob& d) { ch *= d.ch; zn *= d.zn; return *this; } Drob& Drob::operator/=(const Drob& d) { ch *= d.zn; zn *= d.ch; return *this; } Drob& Drob::operator+=(int n) { ch += n * zn; return *this; } Drob& Drob::operator-=(int n) { ch -= n * zn; return *this; } Drob& Drob::operator*=(int n) { ch *= n; return *this; } Drob& Drob::operator/=(int n) { zn *= n; return *this; } // // Перегруженные потоковые операции ввода и вывода // ostream& operator<<(ostream& os, const Drob& d) { os << d.ch << "/" << d.zn; return os; } istream& operator>>(istream& is, Drob& d) { int ach, azn; cout << "Enter a numerator of fraction: "; is >> ach; cout << "Enter a denominator of fraction: "; is >> azn; d.Set(ach, azn); return is; } |
Обратите внимание студентов, что операции (), new и delete в этом классе перегружены исключительно для иллюстрации пройденного материала. Особого практического смысла они не несут. Также следует обратить внимание студентов на используемые функции malloc, free и memset.
Также на этом примере обратите внимание студентов, что нельзя разносить по заголовочным файлам и файлам исходного кода объявления и определения встраиваемых функций. Объясните причины такого ограничения, связанные с работой компилятора и компоновщика.
Окончательный вариант класса «Вектор».
Заголовочный файл:
#ifndef __VECTOR_H__ #define __VECTOR_H__ typedef unsigned int uint; class Vector { private: int *data; uint count; public: // Конструкторы Vector(): data(0), count(0) {} explicit Vector(uint initCount); Vector(const Vector& v); Vector(int array[], uint arraySize); // Деструктор ~Vector() { Clear(); } // Очистка вектора void Clear(); // Присваивание Vector& operator=(const Vector& v); // Работа с размером вектора uint GetCount() const { return count; } bool IsEmpty() const { return count == 0; } bool operator!() const { return IsEmpty(); } // Доступ к элементам int& operator[](uint index); // Добавление и удаление элементов void Add(const int& item); void Insert(uint index, const int& item); void Remove(uint index); }; #endif/* __VECTOR_H__ */ |
Файл с исходным кодом:
#include "vector.h" Vector::Vector(uint initCount) { if (!initCount) data = 0; else data = new int[initCount]; count = initCount; } Vector::Vector(const Vector& v) { if (!v.count) data = 0; else { // Выделяем память и копируем элементы data = new int[v.count]; for (uint i = 0; i < v.count; i++) data[i] = v.data[i]; } count = v.count; } Vector::Vector(int array[], uint arraySize) { if (!arraySize) data = 0; else { // Выделяем память и копируем элементы data = new int[arraySize]; for (uint i = 0; i < arraySize; i++) data[i] = array[i]; } count = arraySize; } void Vector::Clear() { if (count) { delete[] data; data = 0; count = 0; } } Vector& Vector::operator=(const Vector& v) { // Проверка на самоприсваивание if (this == &v) return *this; if (!v.count) { delete[] data; data = 0; } else { // Выделяем память и копируем элементы int *temp = new int[v.count]; for (uint i = 0; i < v.count; i++) temp[i] = v.data[i]; // Удаляем старый массив delete[] data; data = temp; } count = v.count; return *this; } int& Vector::operator[](uint index) { if (index >= count) return data[0]; return data[index]; } void Vector::Add(const int& item) { if (!count) { data = new int; *data = item; } else { // Выделяем память и копируем элементы int *temp = new int[count + 1]; for (uint i = 0; i < count; i++) temp[i] = data[i]; // Добавляем новый элемент temp[count] = item; // Удаляем старый массив delete[] data; data = temp; } count++; } void Vector::Insert(uint index, const int& item) { if (index > count) return; if (!count) { data = new int; *data = item; } else { // Выделяем память и копируем элементы int *temp = new int[count + 1]; for (uint i = 0; i < count; i++) if (i < index) temp[i] = data[i]; else if (i >= index) temp[i + 1] = data[i]; // Вставляем новый элемент temp[index] = item; // Удаляем старый массив delete[] data; data = temp; } count++; } void Vector::Remove(uint index) { if (index >= count) return; if (count == 1) { delete[] data; data = 0; } else { // Выделяем память и копируем элементы int *temp = new int[count - 1]; for (uint i = 0; i < count; i++) if (i < index) temp[i] = data[i]; else if (i > index) temp[i - 1] = data[i]; // Удаляем старый массив delete[] data; data = temp; } count--; } |
Дата добавления: 2014-12-15; просмотров: 86 | Поможем написать вашу работу | Нарушение авторских прав |