// 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 <