// Tablica_Dynamiczna_kolos_PK.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include class Zespolona { double rzeczywista; double urojona; public: Zespolona():rzeczywista(0), urojona(0) {} //nie trzeba tworzyć konstruktorów kopiującego i przenoszącego, bo nie operujemy na //strukturach dynamicznych, gdzie obie struktury miałyby te same wskaźnik Zespolona(double r, double u): rzeczywista(r), urojona(u) {} double getR() const { return rzeczywista; } double getU() const { return urojona; } void setR(const double r):rzeczywista(r) {} void setU(const double u):urojona(u) {} friend std::istream& operator >>(std::istream& s, Zespolona& z) { s >> z.rzeczywista >> z.urojona; return s; } bool operator <(const Zespolona& z) const //ten const to tego, że nie zmieniamy this { return rzeczywista*rzeczywista + urojona*urojona < z.rzeczywista*z.rzeczywista + z.urojona*z.urojona; } }; class Tab { protected: //Zespolona** tablica; dla tablic dynamicznych wsk Zespolona* tablica; unsigned int rozmiar; public: Tab(): tablica(nullptr), rozmiar(0) {} ~Tab() { //dla tablic dynamicznych wsk, a nie obiektów jak niżej //for (int i = 0; i < rozmiar; ++i) // delete tablica[i]; //delete[] tablica; delete[] tablica; } //operator += dodaje element na koniec tablicy virtual void operator +=(const Zespolona& z) { //new Zespolona*[rozmiar + 1]; - dla tablicy wsk auto nowaTab = new Zespolona[rozmiar + 1]; for (unsigned int i = 0; i < rozmiar; ++i) { nowaTab[i] = tablica[i]; //dla tabWsk: nowaTab[i]= new Zespolona(*tablica[i]); //dla tabWsk musimy stworzyć nową tablicę na podstawie tablica[i], i trzeba wyłuskać te wartości } nowaTab[rozmiar] = z; delete[] tablica; tablica = nowaTab; ++rozmiar; } //operator przypisania Tab& operator=(const Tab& t) { //zwraca Tab&, żeby można było to łańcuchować //int a = 5; //int a = b = 5; if (this == &t) //ZAWSZE!!! return *this; delete[] tablica; rozmiar = t.rozmiar; tablica = new Zespolona[rozmiar]; for (unsigned int i = 0; i < rozmiar; ++i) tablica[i] = t.tablica[i]; return *this; } //operator przenoszenia Tab& operator=(Tab&& t) { if (this == &t) //ZAWSZE!!! return *this; delete[] tablica; rozmiar = t.rozmiar; t.rozmiar = 0; tablica = t.tablica; t.tablica = nullptr; } Zespolona operator[](unsigned int i)//const jest do referencji { if (i >= rozmiar) { throw std::exception(); } return tablica[i]; } }; class Kolejka: public Tab { public: void operator+=(const Zespolona& z) override { auto nowaKolejka = new Zespolona[rozmiar + 1]; int i = 0; //wyszukiwanie elementu i przepisywanie elementów do szukanego while (i < rozmiar && tablica[i] < z) { nowaKolejka[i] = tablica[i]; ++i; } //wpisanie nowego elementu nowaKolejka[i] = z; ++rozmiar; ++i; //przepisanie reszty elementów while (i < rozmiar) { nowaKolejka[i] = tablica[i-1]; ++i; } delete[] tablica; tablica = nowaKolejka; } friend std::ostream& operator>>(std::ostream& s, Kolejka& k) { //for (int i = 0; i < rozmiar; ++i) dla tabWSk // delete tablica[i]; dla tabWSk for (int i = 0; i < rozmiar; ++i) { //tablica[i] = new Zespolona(); dla tabWSk s >> tablica[i]; } return s; } operator Zespolona() { double sumaR = 0; double sumaU = 0; for (unsigned int i = 0; i < rozmiar; ++i) { sumaR += tablica[i].getR(); sumaU += tablica[i].getU(); } return Zespolona(sumaR, sumaU); } Zespolona pop() { auto bufor = tablica[0]; auto nowaTab = new Zespolona[rozmiar - 1]; for (unsigned int i = 1; i < rozmiar; ++i) { nowaTab[i - 1] = tablica[i]; } delete[] tablica; --rozmiar; tablica = nowaTab; return bufor; } }; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Kolokwium_lista.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #include class Payment { char* name; double cost; int day; int month; int year; public: //konstruktor 5-cio argumentowy Payment(char *n, double c, int d, int m, int y) : cost(c), day(d), month(m), year(y) { name = new char[strlen(n) + 1]; for (unsigned int i = 0; i <= strlen(n); ++i) name[i] = n[i]; } //konstruktor kopiujący Payment(const Payment& p) : Payment(p.name, p.cost, p.day, p.month, p.year) {} //konstruktor przenoszący Payment(Payment&& p) { name = p.name; day = p.day; month = p.month; year = p.year; cost = p.cost; p.cost = 0; p.day = 0; p.month = 0; p.year = 0; p.name = nullptr; } //operator przypisania Payment& operator=(const Payment& p) { if (this == &p) // ten if na początek każdego operatora = (& i &&) kopiującego i przenoszącego/przypisującego return *this; cost = p.cost; day = p.day; month = p.month; year = p.year; delete[] name; name = new char[strlen(p.name) + 1]; for (unsigned int i = 0; i <= strlen(p.name); ++i) name[i] = p.name[i]; } //operator porównania bool operator<(const Payment& p) const { if (year == p.year) if (month == p.month) return day < p.day; else return month < p.month; else return year < p.year; } //gettery char* getName() const { return name; } double getCost() const { return cost; } int getDay() const { return day; } int getMonth() const { return month; } int getYear() const { return year; } //settery void setName(const char* n):name(n) {} void setCost(const double c): cost(c) {} //itd... //zaprzyjażniony operator strumieniowy friend std::ostream& operator << (std::ostream& s, const Payment& p) { s << p.name << " " << p.cost << " " << p.day << "." << p.month << "." << p.year; return s; } }; struct element { element* next; element* prev; Payment p; //konstruktor kopiujący element(const Payment& other) : next(nullptr), prev(nullptr), p(other) {} }; class List { protected: element* head; element* tail; public: //konstruktor bezargumentowy List() : head(nullptr), tail(nullptr) {} //destruktor ~List() { while (head) { auto bufor = head; head = head->next; delete bufor; } tail = nullptr; } //jak operator ma być przeciążony w klasie pochodnej to stosujemy "virtual" w klasie nadrzednej, a w klasie pochodnej "override", bo nadpisujemy //przeciążony operator += virtual void operator+=(const Payment& p) //typy klasowe moga byc bardzo duze i chcemy uniknac ich kopiowania dlatego & { auto newElement = new element(p); if (tail) { auto bufor = tail; tail = newElement; bufor->next = tail; tail->prev = bufor; } else { tail = head = newElement; } } //jeśli mamy opertator += napisać to robimy to przed konstruktorem, bo go wykorzystujemy //konstruktor kopiujący List(const List& other) { auto ptr = other.head; while (ptr) { *this += ptr->p; ptr = ptr->next; } } //zaprzyjaźniony operator strumieniowy << friend std::ostream& operator <<(std::ostream& s, const List& l) { auto ptr = l.head; while (ptr) { s << ptr->p << std::endl; ptr = ptr->next; } return s; } }; class Queue: public List { public: //nadpisany operator += void operator+=(const Payment& p) override { auto newElement = new element(p); auto ptr = head; while (ptr && p < ptr->p) { ptr = ptr->next; } if (ptr) { auto bufor = ptr->prev; ptr->prev = newElement; if (ptr == head) head = newElement; //czy to jest konieczne? if (bufor) bufor->next = newElement; newElement->prev = bufor; newElement->next = ptr; } else { auto bufor = tail; tail = newElement; if (bufor) { bufor->next = tail; tail->prev = bufor; return; } else { head = tail; } } } //usuwanie listy void deleteList() { while (head) { auto bufor = head; head = head->next; delete bufor; } tail = nullptr; } //operator = przypisania Queue& operator=(const Queue& q) { if (this == &q) return *this; deleteList(); auto ptr = q.head; while (ptr) { *this += ptr->p; ptr = ptr->next; } return *this; } //operatory konwersji zapisuje się: operator TypDoKtoregoKonwertujesz() { funkcja } operator double() { auto ptr = head; auto sum = 0.0; while (ptr) { sum += (ptr->p).getCost(); ptr = ptr->next; } return sum; } Payment pop() { auto toReturn = head->p; auto bufor = head; head = head->next; if (tail == bufor) tail = nullptr; delete bufor; return toReturn; } }; int main() { Queue list; list += Payment("Adam", 50, 4, 12, 1997); list += Payment("Piotr", 30, 5, 12, 1997); list += Payment("Tomasz", 80, 4, 8, 1997); list += Payment("Domek", 25, 14, 1, 1998); list += Payment("Lipa", 60, 17, 2, 1995); list += Payment("Lol", 56, 19, 7, 2000); std::cout << list; Queue l; l = list; std::cout << std::endl << l; std::cout << std::endl << (double)l; std::cout << std::endl << l.pop(); std::cout << std::endl < #include #include using namespace std; /////////////////////////////////////////////////////////////////////////////// class task { string todo = "empty task"; int date = 0; public: task(string, int); task() = default; task(const task &) = default; task & operator=(const task &) = default; void complete(void); int operator>(const task &); // porownoje daty int operator==(const task &); // porownuje cale zadania friend ostream & operator<<(ostream &, const task &); friend istream & operator>>(istream &, task &); }; task::task(string todo, int date) : todo(todo), date(date) {} void task::complete(void) { cout << "\ntask " << todo << " scheduled for " << date << " done successfully!"; } int task::operator>(const task &rt) { return date>rt.date; } int task::operator==(const task &rt) { return ((todo == rt.todo) && (date == rt.date)); } ostream & operator<<(ostream &os, const task &rt) { os << rt.todo; os << " "; os << rt.date; return os; }; istream & operator>>(istream &is, task &rt) { return is >> rt.todo >> rt.date; }; struct q_elem { task t; q_elem * next; q_elem(const task &ctr) :t(ctr), next(nullptr) {}; }; /////////////////////////////////////////////////////////////////////////////// class queue { protected: q_elem *head, /* nullptr dla pustej kolejki */ *tail; /* istotny jesli head != nullptr */ public: queue() :head(nullptr) {} virtual queue & operator+=(const task &rq) // virtual!!! { q_elem *qep = new q_elem(rq); if (head) tail->next = qep; else head = qep; tail = qep; return *this; } queue(const queue &rq) :head(nullptr) { q_elem *qep = rq.head; while (qep) { (*this) += qep->t; qep = qep->next; } } queue(queue &&rrq) : head(rrq.head), tail(rrq.tail) { rrq.head = rrq.tail = nullptr; } ~queue() { while (head) { const q_elem * qep = head; head = head->next; delete qep; } } void empty() // pozostawia obiekt pusty (head==nullptr) { while (head) { const q_elem * qep = head; head = head->next; delete qep; } } queue & operator=(const queue &rq) { if (&rq == this) return *this; empty(); q_elem *qep = rq.head; while (qep) { (*this) += qep->t; qep = qep->next; } return *this; } queue & operator=(queue &&rq) { swap(head, rq.head); swap(tail, rq.tail); return *this; } int contains(const task & ctr) { q_elem *qep = head; while (qep) if (qep->t == ctr) return 1; else qep = qep->next; return 0; } friend istream & operator>>(istream &is, queue &rq) { task t; // wymaga konstruktora bezargumentowego task() rq.empty(); while (is >> t) rq += t; return is; } friend ostream & operator<<(ostream &os, const queue &rq) { q_elem *qep = rq.head; while (qep) { os << qep->t << " "; qep = qep->next; } return os; } }; /////////////////////////////////////////////////////////////////////////////// class sorted_q :public queue { public: sorted_q & operator+=(const task &rq) // inny typ zwracany - ok tutaj { q_elem * const newel = new q_elem(rq); if ((!head) || (head->t > rq)) // wstaw na pocz�tek { newel->next = head; head = newel; } else { q_elem * pq = head; while (pq->next && !(pq->next->t>rq)) pq = pq->next; newel->next = pq->next; pq->next = newel; } if (!newel->next) tail = newel; return *this; } void complete(queue &tobedone) { q_elem *qep = head; while (qep) { if (tobedone.contains(qep->t)) qep->t.complete(); qep = qep->next; } } using queue::operator=; // kolejno�� wywo�ywania konstruktor�w powoduje ze poni�sza deklaracja nie jest potrzebna // // using queue::queue; // automatyczne konwersje o kl. bazowej i metody wirtualne powoduj� �e poni�sze nie s� niezb�dne // // friend istream & operator>>(istream &is, sorted_q &rq) // friend ostream & operator<<(ostream &os, const sorted_q &rq) }; int main() { queue q1; sorted_q s1; q1 += task("task a", 20161020); q1 += task("task b", 20161020); q1 += task("task c", 20161515); q1 += task("task d", 20160505); queue q2 = move(q1); cout << "q1 " << q1 << endl << "q2 " << q2 << endl; q1 = move(q2); cout << "q1 " << q1 << endl << "q2 " << q2 << endl; q2 = q1; q1 += task("task e", 20160505); cout << endl << q1; q1 = q2; cout << endl << q1; s1 = q1; cout << endl << s1; s1 += task("task f", 900000000); s1 += task("task g", 00000); cout << endl << s1; s1.complete(q1); cin >> s1; cout << endl << s1; cout.flush(); }