├── README.md ├── Sem_01 ├── README.md ├── images │ ├── memory.png │ ├── oop.png │ ├── padding.png │ └── union.jpg ├── ipAddress.cpp ├── isLittleEndian.cpp └── triangleAreas.cpp ├── Sem_02 ├── 1. PrintMyOwnCode.cpp ├── 2. CopyFileContent.cpp ├── 3. GetFileSize.cpp ├── 4. GetLinesCountInFile.cpp ├── 5. ReplaceInFile.cpp ├── EnumExample_ConvertStringToNumber.cpp ├── README.md ├── ReadWriteStudents.cpp ├── ReadWriteStudents_CSVFile │ ├── ReadWriteStudents_CSVFile.cpp │ └── students.csv └── images │ ├── ios.gif │ ├── streams.gif │ ├── streams.png │ └── unscopedEnums.png ├── Sem_03 ├── 1. ReadIntArray_BinFile.cpp ├── 1. WriteIntArray_BinFile.cpp ├── 2. ReadWriteStudentsDynamicName_BinaryFile.cpp ├── 3. HexViewer.cpp ├── README.md └── images │ ├── binFile1.png │ ├── binFile1HexViewer.png │ ├── binFile2.png │ └── binFile2HexViewer.png ├── Sem_04 ├── README.md └── images │ └── ConstrDestrOrder.png ├── Sem_05 ├── Date │ ├── Date.cpp │ ├── Date.h │ └── main.cpp ├── Event │ ├── Event.cpp │ ├── Event.h │ └── main.cpp ├── README.md ├── Time │ ├── Time.cpp │ ├── Time.h │ └── main.cpp └── images │ ├── Compilation.png │ ├── Compilation2.png │ ├── HeaderAndCpp.png │ └── Linking.png ├── Sem_06 ├── Big4 examples │ ├── Bitset │ │ ├── Set.cpp │ │ ├── Set.h │ │ └── Source.cpp │ ├── GPSPath │ │ ├── GPSPath.cpp │ │ ├── GPSPath.h │ │ └── Source.cpp │ ├── GraduatedStudent │ │ ├── GraduatedStudent.cpp │ │ ├── GraduatedStudent.h │ │ └── Source.cpp │ └── Person │ │ ├── Person.cpp │ │ ├── Person.h │ │ └── Source.cpp ├── README.md ├── Static examples │ ├── Fibonacci_static_cache │ │ ├── MapKeys0toN.cpp │ │ ├── MapKeys0toN.h │ │ └── Source.cpp │ └── ObjectCounter │ │ ├── ObjectCounter.cpp │ │ ├── ObjectCounter.h │ │ └── Source.cpp └── images │ ├── Constr.png │ ├── CopyConstr.png │ ├── Destr.png │ ├── RealCopy.png │ └── ShallowCopy.png ├── Sem_07 ├── FlightsScanner │ ├── FlightsScanner.cpp │ ├── FlightsScanner.h │ ├── Source.cpp │ ├── Utils.cpp │ ├── Utils.h │ └── inputFlights.txt ├── README.md └── images │ └── StackUnwinding.png ├── Sem_08 ├── 1. ComplexNumber │ ├── ComplexNumber.cpp │ ├── ComplexNumber.h │ └── Source.cpp ├── 2. NVector │ ├── NVector.cpp │ ├── NVector.h │ └── Source.cpp ├── 3. MyString │ ├── MyString.cpp │ ├── MyString.h │ └── Source.cpp ├── README.md └── images │ ├── Operators.png │ └── OperatorsPrecedence.png ├── Sem_09 ├── DynamicArrayOfPointers │ ├── DynamicArrayOfPointers.cpp │ ├── DynamicArrayOfPointers.h │ └── Source.cpp ├── MyString (with move) │ ├── MyString.cpp │ ├── MyString.h │ └── Source.cpp ├── README.md ├── SortedStringPool │ ├── SortedStringPool.cpp │ ├── SortedStringPool.h │ └── Source.cpp ├── UniquePtr │ ├── Source.cpp │ ├── UniquePtrOfA.cpp │ └── UniquePtrOfA.h └── images │ ├── ArrayOfPointers.png │ ├── RVO.png │ ├── WithMove.png │ └── WithoutMove.png ├── Sem_10 ├── InheritanceExample │ ├── Person │ │ ├── Person.cpp │ │ └── Person.h │ ├── Student │ │ ├── Student.cpp │ │ └── Student.h │ └── Teacher │ │ ├── Teacher.cpp │ │ └── Teacher.h ├── README.md ├── Sets │ ├── SetOfNumbers │ │ ├── SetOfNumbers.cpp │ │ ├── SetOfNumbers.h │ │ └── Source.cpp │ └── SetOfNumbersByCriteria │ │ ├── SetOfNumbersByCriteria.cpp │ │ ├── SetOfNumbersByCriteria.h │ │ └── Source.cpp └── images │ ├── PersonStudent.png │ └── Student.png ├── Sem_11 ├── Figures │ ├── Circle │ │ ├── Circle.cpp │ │ └── Circle.h │ ├── Rectangle │ │ ├── Rectangle.cpp │ │ └── Rectangle.h │ ├── Shape │ │ ├── Shape.cpp │ │ └── Shape.h │ ├── Source.cpp │ └── Triangle │ │ ├── Triangle.cpp │ │ └── Triangle.h ├── Figures_mutualCatching │ ├── Circle │ │ ├── Circle.cpp │ │ └── Circle.h │ ├── Rectangle │ │ ├── Rectangle.cpp │ │ └── Rectangle.h │ ├── Shape │ │ ├── Shape.cpp │ │ └── Shape.h │ ├── Source.cpp │ └── Triangle │ │ ├── Triangle.cpp │ │ └── Triangle.h ├── README.md ├── ReadAndWritePolymorphicallyToFiles │ ├── ArrFileReader.cpp │ ├── ArrFileReader.h │ ├── ArrFileWriter.cpp │ ├── ArrFileWriter.h │ ├── BinaryFileReader.cpp │ ├── BinaryFileReader.h │ ├── BinaryFileWriter.cpp │ ├── BinaryFileWriter.h │ ├── CSVFileReader.cpp │ ├── CSVFileReader.h │ ├── CSVFileWriter.cpp │ ├── CSVFileWriter.h │ ├── FilePath.cpp │ ├── FilePath.h │ ├── FileReader.cpp │ ├── FileReader.h │ ├── FileWriter.cpp │ ├── FileWriter.h │ ├── MyString.cpp │ ├── MyString.h │ ├── Source.cpp │ ├── StringView.cpp │ ├── StringView.h │ ├── numbers.arr │ ├── numbers.csv │ ├── numbers.dat │ └── numbers2.arr └── images │ ├── ConstrDestrCallingVirtualMethods.png │ ├── DynamicBindingExampleOutput.png │ ├── StaticBindingExampleOutput.png │ ├── VirtualTables.png │ └── VtableVptr.png ├── Sem_12 ├── AnimalCollection │ ├── AnimalCollection │ │ ├── Farm.cpp │ │ └── Farm.h │ ├── Animals │ │ ├── Animal.h │ │ ├── Cat.cpp │ │ ├── Cat.h │ │ ├── Dog.cpp │ │ ├── Dog.h │ │ ├── Mouse.cpp │ │ └── Mouse.h │ ├── Factory │ │ ├── Factory.cpp │ │ └── Factory.h │ └── Source.cpp ├── AnimalCollection_AbstractFactory │ ├── Animal.cpp │ ├── Animal.h │ ├── AnimalCollection.cpp │ ├── AnimalCollection.h │ ├── AnimalFactory.hpp │ ├── Cat.cpp │ ├── Cat.h │ ├── Dog.cpp │ ├── Dog.h │ ├── Snake.cpp │ ├── Snake.h │ ├── Source.cpp │ └── animals.txt ├── README.md ├── ShapeCollection │ ├── Circle │ │ ├── Circle.cpp │ │ └── Circle.h │ ├── Rectangle │ │ ├── Rectangle.cpp │ │ └── Rectangle.h │ ├── Shape │ │ ├── Shape.cpp │ │ └── Shape.h │ ├── ShapeCollection │ │ ├── ShapeCollection.cpp │ │ └── ShapeCollection.h │ ├── Source.cpp │ └── Triangle │ │ ├── Triangle.cpp │ │ └── Triangle.h └── ShapeCollection_FactoryMethod │ ├── Circle │ ├── Circle.cpp │ └── Circle.h │ ├── Rectangle │ ├── Rectangle.cpp │ └── Rectangle.h │ ├── Shape │ ├── Shape.cpp │ └── Shape.h │ ├── ShapeCollection │ ├── ShapeCollection.cpp │ └── ShapeCollection.h │ ├── ShapeFactory │ ├── ShapeFactory.cpp │ └── ShapeFactory.h │ ├── Source.cpp │ └── Triangle │ ├── Triangle.cpp │ └── Triangle.h ├── Sem_13 ├── Bjarne Stroustrup – Multiple Inheritance for C++.pdf ├── README.md └── images │ ├── ConstrDestr-Multiple_Inheritance.png │ ├── Diamond.jpg │ ├── Multiple_Inheritance.png │ ├── Multiple_Inheritance1.png │ └── Multiple_Inheritance2.png ├── Sem_14 ├── FunctionAverage │ ├── FunctionFromFile.hpp │ ├── IntFunctionAverage.hpp │ ├── Source.cpp │ └── test.dat ├── Optional │ └── Optional.hpp ├── Pair │ └── Pair.hpp ├── README.md ├── SetsTask.pdf └── SharedPtr │ ├── SharedPtr.hpp │ └── Source.cpp └── Sem_15 ├── BooleanExpressionCalculator ├── BooleanExpressionHandler.cpp ├── BooleanExpressionHandler.h └── Source.cpp ├── Chess ├── ChessBoard │ ├── ChessBoard.cpp │ └── ChessBoard.h ├── FigureFactory │ ├── FigureFactory.cpp │ └── FigureFactory.h ├── Figures │ ├── Bishop │ │ ├── Bishop.cpp │ │ └── Bishop.h │ ├── Figure │ │ └── Figure.h │ ├── King │ │ ├── King.cpp │ │ └── King.h │ ├── Knight │ │ ├── Knight.cpp │ │ └── Knight.h │ ├── Pawn │ │ ├── Pawn.cpp │ │ └── Pawn.h │ ├── Queen │ │ ├── Queen.cpp │ │ └── Queen.h │ └── Rook │ │ ├── Rook.cpp │ │ └── Rook.h └── Source.cpp ├── README.md ├── SetCalculator ├── Calculator │ ├── SetCalculator.cpp │ └── SetCalculator.h ├── Operation.cpp ├── Operation.h ├── SetExpression.h ├── Singleton.cpp ├── Singleton.h └── Source.cpp ├── TypeCasting └── TypeCastingPlayground.cpp └── images ├── SetExpression_1.png ├── SetExpression_2.png └── SetExpression_3.png /README.md: -------------------------------------------------------------------------------- 1 | ## Код от семинарите по "Обектно-ориентирано програмиране", летен семестър 2023/2024, спец. "Информатика" ## 2 | 3 | - **Тема 1** : Увод в ООП. Структури. Създаване на инстанции. Подаване/връщане на инстанции във/от функции. Подравняване (alignment). Padding. Обединения (union). 4 | - **Тема 2** : Енумерации (plain enum и enum class). Namespaces. Потоци (streams). Текстови файлове. Четене и писане от/в текстов файл. Режими на работа. Put и get указатели. Пример за работа със CSV файлове. 5 | - **Тема 3** : Двоични файлове. Четене и писане от/в двоичен файл. Реализация на прост Hex Viewer. 6 | - **Тема 4** : Член-функции (методи). Конструктори и деструктор. Ред на работа на конструкторите и деструкторите. Конструктори и деструктор при композиция на обекти. Капсулация (encapsulation). Accessors and mutators (гетъри и сетъри). 7 | - **Тема 5** : Процес на компилация. Разделна компилация – .h файлове и .cpp файлове. 8 | - **Тема 6** : Динамична памет в структури/класове. Голямата четворка (Big 4). Ключова дума static. 9 | - **Тема 7** : Изключения (Exceptions). 10 | - **Тема 8** : Предефиниране на оператори (Operator overloading). Приятелски класове и функции. 11 | - **Тема 9** : Value categories – glvalue, prvalue, xvalue, lvalue, rvalue. Move семантики. Масиви от указатели към обекти. 12 | - **Тема 10** : Наследяване (Is-a relationship). 13 | - **Тема 11** : Статично и динамично свързване. Виртуални функции. Ключови думи – override и final. Полиморфизъм. Чисто виртуални функции и абстрактни класове. 14 | - **Тема 12** : Колекции от обекти в полиморфна йерархия. Factory method. 15 | - **Тема 13** : Множествено наследяване. Диамантен проблем. 16 | - **Тема 14** : Параметричен полиморфизъм (шаблони). 17 | - **Тема 15** : Дървовидна структура от обекти от полиморфна йерархия. Шах. Тype casting. 18 | -------------------------------------------------------------------------------- /Sem_01/images/memory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_01/images/memory.png -------------------------------------------------------------------------------- /Sem_01/images/oop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_01/images/oop.png -------------------------------------------------------------------------------- /Sem_01/images/padding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_01/images/padding.png -------------------------------------------------------------------------------- /Sem_01/images/union.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_01/images/union.jpg -------------------------------------------------------------------------------- /Sem_01/ipAddress.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | union IpAddress 4 | { 5 | uint32_t address; 6 | unsigned char octets[4]; 7 | }; 8 | 9 | int main() 10 | { 11 | IpAddress myAddress; 12 | myAddress.address = 16777343; 13 | 14 | std::cout << (int)myAddress.octets[0] << "." 15 | << (int)myAddress.octets[1] << "." 16 | << (int)myAddress.octets[2] << "." 17 | << (int)myAddress.octets[3]; 18 | } 19 | -------------------------------------------------------------------------------- /Sem_01/isLittleEndian.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | bool isLittleEndian() 4 | { 5 | union endiannessTest 6 | { 7 | uint32_t n = 1; 8 | unsigned char bytes[4]; 9 | } myTest; 10 | 11 | return myTest.bytes[0]; 12 | } 13 | 14 | int main() 15 | { 16 | std::cout << isLittleEndian(); 17 | } 18 | -------------------------------------------------------------------------------- /Sem_01/triangleAreas.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | struct Point 5 | { 6 | int x; 7 | int y; 8 | }; 9 | void readPoint(Point& p) 10 | { 11 | std::cin >> p.x >> p.y; 12 | } 13 | 14 | struct Triangle 15 | { 16 | Point p1; 17 | Point p2; 18 | Point p3; 19 | }; 20 | void readTriangle(Triangle& t) 21 | { 22 | readPoint(t.p1); 23 | readPoint(t.p2); 24 | readPoint(t.p3); 25 | } 26 | 27 | double getDist(const Point& p1, const Point& p2) 28 | { 29 | int dx = p1.x - p2.x; 30 | int dy = p1.y - p2.y; 31 | 32 | return sqrt(dx * dx + dy * dy); 33 | } 34 | 35 | double getArea(const Triangle& t) 36 | { 37 | double sideA = getDist(t.p1, t.p2); 38 | double sideB = getDist(t.p2, t.p3); 39 | double sideC = getDist(t.p3, t.p1); 40 | 41 | double halfPer = (sideA + sideB + sideC) / 2; 42 | return sqrt(halfPer * (halfPer - sideA) * (halfPer - sideB) * (halfPer - sideC)); 43 | } 44 | 45 | double* getAreas(const Triangle* arr, size_t size) 46 | { 47 | double* areas = new double[size]; 48 | for (size_t i = 0; i < size; i++) 49 | { 50 | areas[i] = getArea(arr[i]); 51 | } 52 | return areas; 53 | } 54 | 55 | void sortAreas(double* areas, size_t size) 56 | { 57 | for (size_t i = 0; i < size - 1; i++) 58 | { 59 | size_t minIndex = i; 60 | for (size_t j = minIndex + 1; j < size; j++) 61 | { 62 | if (areas[j] < areas[minIndex]) 63 | { 64 | minIndex = j; 65 | } 66 | } 67 | if (minIndex != i) 68 | { 69 | std::swap(areas[minIndex], areas[i]); 70 | } 71 | } 72 | } 73 | 74 | int main() 75 | { 76 | unsigned int n; 77 | std::cout << "Enter number of triangles:" << std::endl; 78 | std::cin >> n; 79 | 80 | Triangle* triangles = new Triangle[n]; 81 | for (size_t i = 0; i < n; i++) 82 | { 83 | std::cout << "Enter triangle:" << std::endl; 84 | readTriangle(triangles[i]); 85 | } 86 | std::cout << std::endl; 87 | 88 | double* areas = getAreas(triangles, n); 89 | sortAreas(areas, n); 90 | 91 | std::cout << "Sorted areas:" << std::endl; 92 | for (size_t i = 0; i < n; i++) 93 | { 94 | std::cout << "Area of triangle " << i << ": " << areas[i] << std::endl; 95 | } 96 | 97 | delete[] triangles, areas; 98 | } -------------------------------------------------------------------------------- /Sem_02/1. PrintMyOwnCode.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int main() 5 | { 6 | const size_t BUFF_SIZE = 1024; 7 | 8 | std::ifstream file("printMyOwnCode.cpp"); 9 | if (!file.is_open()) 10 | { 11 | std::cout << "File can't be opened!" << std::endl; 12 | return -1; 13 | } 14 | 15 | char buff[BUFF_SIZE]; 16 | while (!file.eof()) 17 | { 18 | file.getline(buff, BUFF_SIZE); 19 | std::cout << buff << std::endl; 20 | } 21 | 22 | file.close(); 23 | } 24 | -------------------------------------------------------------------------------- /Sem_02/2. CopyFileContent.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void copyFileContent(const char* srcName, const char* destName) 5 | { 6 | std::ifstream ifs(srcName); 7 | if (!ifs.is_open()) 8 | { 9 | return; 10 | } 11 | 12 | std::ofstream ofs(destName, std::ios::trunc); 13 | if (!ofs.is_open()) 14 | { 15 | return; 16 | } 17 | 18 | constexpr size_t BUFF_SIZE = 1024; 19 | while (!ifs.eof()) 20 | { 21 | char buff[BUFF_SIZE]; 22 | ifs.getline(buff, BUFF_SIZE); 23 | ofs << buff << std::endl; 24 | } 25 | } 26 | 27 | int main() 28 | { 29 | copyFileContent("src.txt", "dest.txt"); 30 | } 31 | -------------------------------------------------------------------------------- /Sem_02/3. GetFileSize.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | size_t getFileSize(std::ifstream& file) 5 | { 6 | unsigned int currentPos = file.tellg(); 7 | file.seekg(0, std::ios::end); 8 | 9 | size_t fileSize = file.tellg(); 10 | file.seekg(currentPos); 11 | 12 | return fileSize; 13 | } 14 | 15 | int main() 16 | { 17 | 18 | } 19 | -------------------------------------------------------------------------------- /Sem_02/4. GetLinesCountInFile.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | unsigned getCharCountFromFile(std::ifstream& ifs, char ch) 5 | { 6 | if (!ifs.is_open()) 7 | { 8 | return 0; 9 | } 10 | 11 | size_t currentPos = ifs.tellg(); 12 | ifs.seekg(0, std::ios::beg); 13 | 14 | unsigned count = 0; 15 | while (!ifs.eof()) 16 | { 17 | char current = ifs.get(); 18 | if (current == ch) 19 | { 20 | count++; 21 | } 22 | } 23 | 24 | ifs.clear(); 25 | ifs.seekg(currentPos); 26 | return count; 27 | } 28 | 29 | unsigned getLinesCount(const char* fileName) 30 | { 31 | std::ifstream myFile(fileName); 32 | if (!myFile.is_open()) 33 | { 34 | return 0; 35 | } 36 | 37 | return getCharCountFromFile(myFile, '\n') + 1; 38 | } 39 | 40 | int main() 41 | { 42 | std::cout << getLinesCount("file.txt"); 43 | } 44 | -------------------------------------------------------------------------------- /Sem_02/5. ReplaceInFile.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void replaceInFile(char toBeReplaced, char toReplaceWith, std::fstream& file) 5 | { 6 | while (!file.eof()) 7 | { 8 | char currentSymbol = file.get(); 9 | 10 | if (currentSymbol != toBeReplaced) 11 | continue; 12 | 13 | file.seekp(-1, std::ios::cur); 14 | file.put(toReplaceWith); 15 | file.flush(); 16 | } 17 | } 18 | 19 | int main() 20 | { 21 | std::fstream file("file.txt", std::ios::in | std::ios::out); 22 | if (!file.is_open()) 23 | { 24 | std::cout << "Error opening the file!" << std::endl; 25 | return -1; 26 | } 27 | 28 | replaceInFile('a', 'X', file); 29 | } 30 | -------------------------------------------------------------------------------- /Sem_02/EnumExample_ConvertStringToNumber.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | enum class ErrorCode 4 | { 5 | OK, 6 | InvalidSymbol, 7 | EmptyString, 8 | NullptrGiven 9 | }; 10 | 11 | struct ConvertResult 12 | { 13 | ErrorCode errorCode; 14 | unsigned result; 15 | }; 16 | 17 | bool isDigit(char ch) 18 | { 19 | return ch >= '0' && ch <= '9'; 20 | } 21 | unsigned short convertCharToDigit(char ch) 22 | { 23 | return ch - '0'; 24 | } 25 | 26 | ConvertResult convertStringToNumber(const char* str) 27 | { 28 | if (!str) 29 | { 30 | return { ErrorCode::NullptrGiven, 0 }; 31 | } 32 | 33 | if (*str == '\0') 34 | { 35 | return { ErrorCode::EmptyString, 0 }; 36 | } 37 | 38 | unsigned num = 0; 39 | while (*str) 40 | { 41 | if (!isDigit(*str)) 42 | { 43 | return { ErrorCode::InvalidSymbol, 0 }; 44 | } 45 | (num *= 10) += convertCharToDigit(*str); 46 | str++; 47 | } 48 | 49 | return { ErrorCode::OK, num }; 50 | } 51 | 52 | int main() 53 | { 54 | ConvertResult convertedNum = convertStringToNumber("12343"); 55 | 56 | if (convertedNum.errorCode == ErrorCode::OK) 57 | { 58 | std::cout << convertedNum.result << std::endl; 59 | } 60 | else 61 | { 62 | std::cout << "Error!" << std::endl; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Sem_02/ReadWriteStudents.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | enum class Мajor 5 | { 6 | CS, 7 | I, 8 | SE, 9 | IS 10 | }; 11 | 12 | struct Student 13 | { 14 | char name[32]; 15 | int age; 16 | Мajor major; 17 | }; 18 | 19 | void saveStudentToFile(std::ofstream& ofs, const Student& st) 20 | { 21 | ofs << st.name << std::endl; 22 | ofs << st.age << std::endl; 23 | ofs << static_cast(st.major) << std::endl; 24 | } 25 | 26 | void readStudentFromFile(std::ifstream& ifs, Student& st) 27 | { 28 | ifs.getline(st.name, 32); 29 | ifs >> st.age; 30 | ifs.ignore(); // ignore the \n 31 | int majorInt; 32 | ifs >> majorInt; 33 | st.major = static_cast<Мajor>(majorInt); 34 | ifs.ignore(); // ignore the \n 35 | } 36 | 37 | void writeArrayToFile(const char* fileName, const Student* students, const size_t size) 38 | { 39 | std::ofstream ofs(fileName); 40 | if (!ofs.is_open()) 41 | { 42 | return; 43 | } 44 | 45 | ofs << size << std::endl; 46 | for (size_t i = 0; i < size; i++) 47 | { 48 | saveStudentToFile(ofs, students[i]); 49 | } 50 | ofs.close(); 51 | } 52 | 53 | Student* readArrayFromFile(const char* fileName, size_t& size) 54 | { 55 | std::ifstream ifs(fileName); 56 | if (!ifs.is_open()) 57 | { 58 | return nullptr; 59 | } 60 | 61 | ifs >> size; 62 | ifs.ignore(); 63 | Student* result = new Student[size]; 64 | 65 | for (size_t i = 0; i < size; i++) 66 | { 67 | readStudentFromFile(ifs, result[i]); 68 | } 69 | ifs.close(); 70 | return result; 71 | } 72 | 73 | int main() 74 | { 75 | Student students[] = { {"Galya", 34, Мajor::CS}, { "Georgi", 35, Мajor::I } }; 76 | 77 | writeArrayToFile("students.txt", students, 2); 78 | size_t size; 79 | Student* result = readArrayFromFile("students.txt", size); 80 | for (size_t i = 0; i < size; i++) 81 | { 82 | std::cout << result[i].name << " " << result[i].age <<" " << (int)result[i].major << std::endl; 83 | } 84 | 85 | delete[] result; 86 | } 87 | -------------------------------------------------------------------------------- /Sem_02/ReadWriteStudents_CSVFile/students.csv: -------------------------------------------------------------------------------- 1 | First name,Last name,Email address,FN 2 | Antonio,Petrov,antonio95@abv.bg,0MI0600123 3 | Ekaterina,Dimova,kati@mail.bg,2MI0800100 4 | Stefany,Angelova,stef@gmail.com,3MI0404321 5 | Katerina,Vassileva,katerina@yahoo.com,1MI0400555 6 | Robert,Angelov,robert@hotmail.com,5MI0811011 -------------------------------------------------------------------------------- /Sem_02/images/ios.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_02/images/ios.gif -------------------------------------------------------------------------------- /Sem_02/images/streams.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_02/images/streams.gif -------------------------------------------------------------------------------- /Sem_02/images/streams.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_02/images/streams.png -------------------------------------------------------------------------------- /Sem_02/images/unscopedEnums.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_02/images/unscopedEnums.png -------------------------------------------------------------------------------- /Sem_03/1. ReadIntArray_BinFile.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | size_t getFileSize(std::ifstream& file) 5 | { 6 | unsigned int currentPos = file.tellg(); 7 | file.seekg(0, std::ios::end); 8 | 9 | size_t fileSize = file.tellg(); 10 | file.seekg(currentPos); 11 | 12 | return fileSize; 13 | } 14 | 15 | int main() 16 | { 17 | std::ifstream ifs("file.dat", std::ios::binary); 18 | if (!ifs.is_open()) 19 | { 20 | return -1; 21 | } 22 | 23 | size_t fileSize = getFileSize(ifs); 24 | size_t arrSize = fileSize / sizeof(int); 25 | 26 | int* arr = new int[arrSize]; 27 | ifs.read(reinterpret_cast(arr), fileSize); 28 | 29 | for (size_t i = 0; i < arrSize; i++) 30 | { 31 | std::cout << arr[i] << ' '; 32 | } 33 | 34 | delete[] arr; 35 | ifs.close(); 36 | } 37 | -------------------------------------------------------------------------------- /Sem_03/1. WriteIntArray_BinFile.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main() 4 | { 5 | std::ofstream ofs("file.dat", std::ios::binary); 6 | if (!ofs.is_open()) 7 | { 8 | return -1; 9 | } 10 | 11 | int arr[] = { 1, 2, 3, 4, 5 }; 12 | ofs.write(reinterpret_cast(arr), sizeof(arr)); 13 | 14 | ofs.close(); 15 | } 16 | -------------------------------------------------------------------------------- /Sem_03/3. HexViewer.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | struct HexViewerFile 6 | { 7 | unsigned char* data; 8 | size_t dataSize; 9 | }; 10 | 11 | void freeHexViewerFile(HexViewerFile& file) 12 | { 13 | delete[] file.data; 14 | file.dataSize = 0; 15 | } 16 | 17 | size_t getFileSize(std::ifstream& file) 18 | { 19 | unsigned int currentPos = file.tellg(); 20 | file.seekg(0, std::ios::end); 21 | 22 | size_t fileSize = file.tellg(); 23 | file.seekg(currentPos); 24 | 25 | return fileSize; 26 | } 27 | 28 | HexViewerFile init(const char* filePath) 29 | { 30 | std::ifstream ifs(filePath, std::ios::binary); 31 | HexViewerFile myFile; 32 | 33 | if (!ifs.is_open()) 34 | { 35 | myFile.data = nullptr; 36 | myFile.dataSize = 0; 37 | return myFile; 38 | } 39 | 40 | myFile.dataSize = getFileSize(ifs); 41 | myFile.data = new unsigned char[myFile.dataSize]; 42 | ifs.read(reinterpret_cast(myFile.data), myFile.dataSize); 43 | 44 | ifs.close(); 45 | return myFile; 46 | } 47 | 48 | bool isValidSymbol(char ch) 49 | { 50 | return ch >= 'a' && ch <= 'z' || 51 | ch >= 'A' && ch <= 'Z' || 52 | ch >= '0' && ch <= '9'; 53 | } 54 | 55 | void print(const HexViewerFile& myFile) 56 | { 57 | for (size_t i = 0; i < myFile.dataSize; i++) 58 | { 59 | std::cout << std::hex << std::setw(2) << std::setfill('0') << (int)myFile.data[i] << ' '; 60 | } 61 | std::cout << std::endl; 62 | 63 | for (size_t i = 0; i < myFile.dataSize; i++) 64 | { 65 | if (isValidSymbol(myFile.data[i])) 66 | { 67 | std::cout << myFile.data[i] << " "; 68 | } 69 | else 70 | { 71 | std::cout << ".. "; 72 | } 73 | } 74 | std::cout << std::endl; 75 | } 76 | 77 | int main() 78 | { 79 | HexViewerFile myFile = init("myFile.dat"); 80 | print(myFile); 81 | freeHexViewerFile(myFile); 82 | } 83 | -------------------------------------------------------------------------------- /Sem_03/images/binFile1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_03/images/binFile1.png -------------------------------------------------------------------------------- /Sem_03/images/binFile1HexViewer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_03/images/binFile1HexViewer.png -------------------------------------------------------------------------------- /Sem_03/images/binFile2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_03/images/binFile2.png -------------------------------------------------------------------------------- /Sem_03/images/binFile2HexViewer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_03/images/binFile2HexViewer.png -------------------------------------------------------------------------------- /Sem_04/images/ConstrDestrOrder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_04/images/ConstrDestrOrder.png -------------------------------------------------------------------------------- /Sem_05/Date/Date.cpp: -------------------------------------------------------------------------------- 1 | #include "Date.h" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | namespace 8 | { 9 | bool isLeapYear(unsigned year) 10 | { 11 | if (year <= 1916) 12 | { 13 | return year % 4 == 0; 14 | } 15 | return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0); 16 | } 17 | } 18 | 19 | Date::Date(unsigned day, unsigned month, unsigned year) 20 | { 21 | setYear(year); 22 | setMonth(month); 23 | setDay(day); 24 | } 25 | 26 | void Date::setYear(unsigned year) 27 | { 28 | if (isLeapYear(year)) 29 | { 30 | maxDays[1] = 29; // February 31 | } 32 | else 33 | { 34 | maxDays[1] = 28; 35 | } 36 | 37 | this->year = year; 38 | isModified = true; 39 | assert(isDateValid()); 40 | } 41 | 42 | void Date::setMonth(unsigned month) 43 | { 44 | this->month = month; 45 | isModified = true; 46 | assert(isDateValid()); 47 | } 48 | 49 | void Date::setDay(unsigned day) 50 | { 51 | this->day = day; 52 | isModified = true; 53 | assert(isDateValid()); 54 | } 55 | 56 | unsigned Date::getYear() const 57 | { 58 | return year; 59 | } 60 | 61 | unsigned Date::getMonth() const 62 | { 63 | return month; 64 | } 65 | 66 | unsigned Date::getDay() const 67 | { 68 | return day; 69 | } 70 | 71 | unsigned Date::getDayOfWeek() const 72 | { 73 | if (!isModified) 74 | { 75 | return dayOfWeek; 76 | } 77 | 78 | Date date(1, 1, 1); 79 | unsigned dayOfWeek = 5; // 0-Monday, 1-Tuesday,.., 6-Sunday (On 01.01.01 was Saturday) 80 | 81 | while (compareDates(*this, date) != 0) // simple and dumb algorithm 82 | { 83 | date.goNextDay(); 84 | (dayOfWeek += 1) %= 7; 85 | } 86 | 87 | this->dayOfWeek = dayOfWeek; 88 | isModified = false; 89 | return this->dayOfWeek; 90 | } 91 | 92 | void Date::goNextDay() 93 | { 94 | if (compareDates(*this, Date(31, 3, 1916)) == 0) 95 | { 96 | setDay(14); 97 | setMonth(4); 98 | return; 99 | } 100 | 101 | day++; 102 | if (day > maxDays[month - 1]) 103 | { 104 | day = 1; 105 | setMonth(month == 12 ? 1 : month + 1); 106 | 107 | if (month == 1) 108 | { 109 | setYear(year + 1); 110 | } 111 | } 112 | } 113 | 114 | void Date::serialize(std::ostream& os) const 115 | { 116 | using namespace std; 117 | os << setw(2) << setfill('0') << day << '.' << setw(2) << setfill('0') << month << '.'; 118 | os << setw(4) << setfill('0') << year << endl; 119 | } 120 | 121 | bool Date::isDateValid() const 122 | { 123 | return !((month == 0 || month > 12) 124 | || (day == 0 || day > maxDays[month - 1]) 125 | || (year == 0) 126 | || (year == 1916 && month == 4 && day < 14)); // due to the transition from Julian to Gregorian 127 | } 128 | 129 | int compareDates(const Date& lhs, const Date& rhs) 130 | { 131 | if (lhs.getYear() == rhs.getYear()) 132 | { 133 | if (lhs.getMonth() == rhs.getMonth()) 134 | { 135 | return lhs.getDay() - rhs.getDay(); 136 | } 137 | else 138 | { 139 | return lhs.getMonth() - rhs.getMonth(); 140 | } 141 | } 142 | else 143 | { 144 | return lhs.getYear() - rhs.getYear(); 145 | } 146 | } -------------------------------------------------------------------------------- /Sem_05/Date/Date.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | class Date 6 | { 7 | private: 8 | unsigned day = 1; 9 | unsigned month = 1; 10 | unsigned year = 1; 11 | 12 | unsigned maxDays[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; 13 | 14 | // These can be changed by constant functions. 15 | mutable unsigned dayOfWeek; 16 | mutable bool isModified; 17 | 18 | bool isDateValid() const; 19 | 20 | public: 21 | Date(unsigned day, unsigned month, unsigned year); 22 | 23 | void setYear(unsigned year); 24 | void setMonth(unsigned month); 25 | void setDay(unsigned day); 26 | 27 | unsigned getYear() const; 28 | unsigned getMonth() const; 29 | unsigned getDay() const; 30 | 31 | unsigned getDayOfWeek() const; 32 | 33 | void goNextDay(); 34 | 35 | void serialize(std::ostream& os) const; 36 | }; 37 | 38 | int compareDates(const Date& lhs, const Date& rhs); -------------------------------------------------------------------------------- /Sem_05/Date/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Date.h" 2 | 3 | int main() 4 | { 5 | Date d(26, 3, 2024); 6 | d.serialize(std::cout); 7 | 8 | d.goNextDay(); 9 | d.goNextDay(); 10 | d.serialize(std::cout); 11 | 12 | d.goNextDay(); 13 | d.goNextDay(); 14 | d.goNextDay(); 15 | d.goNextDay(); 16 | d.serialize(std::cout); 17 | 18 | std::cout << compareDates({ 1,1,2024 }, { 31, 12, 2023 }) << std::endl; 19 | } -------------------------------------------------------------------------------- /Sem_05/Event/Event.cpp: -------------------------------------------------------------------------------- 1 | #include "Event.h" 2 | #include 3 | 4 | #pragma warning(disable : 4996) 5 | 6 | Event::Event() : Event("", 1, 1, 1, 0, 0, 0, 0, 0, 0) 7 | {} 8 | 9 | Event::Event(const char* name, const Date& date, const Time& startTime, const Time& endTime) : date(date), startTime(startTime), endTime(endTime) 10 | { 11 | setName(name); 12 | validateTimes(); 13 | } 14 | 15 | Event::Event(const char* name, unsigned day, unsigned month, unsigned year, 16 | unsigned startTimeHours, unsigned startTimeMins, unsigned startTimeSecs, 17 | unsigned endTimeHours, unsigned endTimeMins, unsigned endTimeSecs) : date(day, month, year), 18 | startTime(startTimeHours, startTimeMins, startTimeSecs), 19 | endTime(endTimeHours, endTimeMins, endTimeSecs) 20 | { 21 | setName(name); 22 | validateTimes(); 23 | } 24 | 25 | const char* Event::getName() const 26 | { 27 | return name; 28 | } 29 | 30 | const Date& Event::getDate() const 31 | { 32 | return date; 33 | } 34 | 35 | const Time& Event::getStartTime() const 36 | { 37 | return startTime; 38 | } 39 | 40 | const Time& Event::getEndTime() const 41 | { 42 | return endTime; 43 | } 44 | 45 | void Event::setName(const char* str) 46 | { 47 | if (strlen(str) > 20) 48 | { 49 | return; 50 | } 51 | else 52 | { 53 | strcpy(name, str); 54 | } 55 | } 56 | 57 | void Event::validateTimes() 58 | { 59 | if (compareTimes(startTime, endTime) >= 1) 60 | { 61 | std::swap(startTime, endTime); 62 | } 63 | } -------------------------------------------------------------------------------- /Sem_05/Event/Event.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "Time.h" 4 | #include "Date.h" 5 | 6 | class Event 7 | { 8 | private: 9 | char name[21]; 10 | Date date; 11 | Time startTime; 12 | Time endTime; 13 | 14 | void setName(const char* str); 15 | void validateTimes(); 16 | 17 | public: 18 | Event(); 19 | Event(const char* name, const Date& date, const Time& startTime, const Time& endTime); 20 | Event(const char* name, unsigned day, unsigned month, unsigned year, 21 | unsigned startTimeHours, unsigned startTimeMins, unsigned startTimeSecs, 22 | unsigned endTimeHours, unsigned endTimeMins, unsigned endTimeSecs); 23 | 24 | const char* getName() const; 25 | const Date& getDate() const; 26 | const Time& getStartTime() const; 27 | const Time& getEndTime() const; 28 | }; -------------------------------------------------------------------------------- /Sem_05/Event/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Event.h" 2 | 3 | int main() 4 | { 5 | Event e("Party", 31, 5, 2024, 20, 30, 00, 23, 30, 00); 6 | std::cout << e.getName(); 7 | } -------------------------------------------------------------------------------- /Sem_05/Time/Time.cpp: -------------------------------------------------------------------------------- 1 | #include "Time.h" 2 | 3 | #include 4 | #include 5 | 6 | Time::Time(unsigned hours, unsigned mins, unsigned seconds) 7 | { 8 | setHours(hours); 9 | setMinutes(mins); 10 | setSeconds(seconds); 11 | } 12 | 13 | bool Time::setHours(unsigned hours) 14 | { 15 | return validateAndSet(0, 23, hours, getHours(), SECONDS_IN_HOURS); 16 | } 17 | 18 | bool Time::setMinutes(unsigned minutes) 19 | { 20 | return validateAndSet(0, 59, minutes, getMinutes(), SECONDS_IN_MINUTE); 21 | } 22 | 23 | bool Time::setSeconds(unsigned seconds) 24 | { 25 | return validateAndSet(0, 59, seconds, getSeconds(), 1); 26 | } 27 | 28 | unsigned Time::getHours() const 29 | { 30 | return secondsFromMidnight / SECONDS_IN_HOURS; 31 | } 32 | 33 | unsigned Time::getMinutes() const 34 | { 35 | return (secondsFromMidnight / SECONDS_IN_MINUTE) % 60; 36 | } 37 | 38 | unsigned Time::getSeconds() const 39 | { 40 | return secondsFromMidnight % 60; 41 | } 42 | 43 | unsigned Time::getTimeInSeconds() const 44 | { 45 | return secondsFromMidnight; 46 | } 47 | 48 | void Time::tick() 49 | { 50 | ++secondsFromMidnight %= DAY_SECONDS; 51 | } 52 | 53 | void Time::serialize(std::ostream& os) const 54 | { 55 | using namespace std; 56 | os << setw(2) << setfill('0') << getHours() << ":" 57 | << setw(2) << setfill('0') << getMinutes() << ":" 58 | << setw(2) << setfill('0') << getSeconds() << endl; 59 | } 60 | 61 | bool Time::validateAndSet(unsigned lowerBound, unsigned upperBound, unsigned newValue, unsigned oldValue, unsigned multiplier) 62 | { 63 | if (newValue >= lowerBound && newValue <= upperBound) 64 | { 65 | (secondsFromMidnight -= (oldValue * multiplier)) += (newValue * multiplier); 66 | return true; 67 | } 68 | else 69 | { 70 | return false; 71 | } 72 | } 73 | 74 | int compareTimes(const Time& lhs, const Time& rhs) 75 | { 76 | return lhs.getTimeInSeconds() - rhs.getTimeInSeconds(); 77 | } 78 | -------------------------------------------------------------------------------- /Sem_05/Time/Time.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | constexpr unsigned SECONDS_IN_HOURS = 3600; 6 | constexpr unsigned SECONDS_IN_MINUTE = 60; 7 | constexpr unsigned DAY_SECONDS = 24 * 3600; 8 | 9 | class Time 10 | { 11 | private: 12 | unsigned secondsFromMidnight = 0; 13 | 14 | bool validateAndSet(unsigned lowerBound, unsigned upperBound, unsigned newValue, unsigned oldVlaue, unsigned multiplier); 15 | 16 | public: 17 | Time() = default; 18 | Time(unsigned hours, unsigned minutes, unsigned seconds); 19 | 20 | bool setHours(unsigned hours); 21 | bool setMinutes(unsigned minutes); 22 | bool setSeconds(unsigned seconds); 23 | 24 | unsigned getHours() const; 25 | unsigned getMinutes() const; 26 | unsigned getSeconds() const; 27 | unsigned getTimeInSeconds() const; 28 | 29 | void tick(); 30 | void serialize(std::ostream& os) const; 31 | }; 32 | 33 | int compareTimes(const Time& lhs, const Time& rhs); 34 | -------------------------------------------------------------------------------- /Sem_05/Time/main.cpp: -------------------------------------------------------------------------------- 1 | #include "Time.h" 2 | 3 | int main() 4 | { 5 | Time t(15, 15, 33); 6 | t.serialize(std::cout); 7 | 8 | t.tick(); 9 | t.tick(); 10 | t.serialize(std::cout); 11 | } -------------------------------------------------------------------------------- /Sem_05/images/Compilation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_05/images/Compilation.png -------------------------------------------------------------------------------- /Sem_05/images/Compilation2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_05/images/Compilation2.png -------------------------------------------------------------------------------- /Sem_05/images/HeaderAndCpp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_05/images/HeaderAndCpp.png -------------------------------------------------------------------------------- /Sem_05/images/Linking.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_05/images/Linking.png -------------------------------------------------------------------------------- /Sem_06/Big4 examples/Bitset/Set.cpp: -------------------------------------------------------------------------------- 1 | #include "Set.h" 2 | 3 | Set::Set(unsigned n) 4 | { 5 | bucketsCount = n / elementsInBucket + 1; 6 | buckets = new uint8_t[bucketsCount]{ 0 }; 7 | this->n = n; 8 | } 9 | 10 | Set::Set(const Set& other) 11 | { 12 | copyFrom(other); 13 | } 14 | 15 | Set& Set::operator=(const Set& other) 16 | { 17 | if (this != &other) 18 | { 19 | free(); 20 | copyFrom(other); 21 | } 22 | return *this; 23 | } 24 | 25 | Set::~Set() 26 | { 27 | free(); 28 | } 29 | 30 | void Set::add(unsigned num) 31 | { 32 | if (num > n) 33 | { 34 | return; 35 | } 36 | 37 | unsigned bucketIndex = getBucketIndex(num); 38 | unsigned bitIndex = getBitIndex(num); 39 | 40 | uint8_t mask = 1 << bitIndex; 41 | buckets[bucketIndex] |= mask; 42 | } 43 | 44 | void Set::remove(unsigned num) 45 | { 46 | if (num > n) 47 | { 48 | return; 49 | } 50 | 51 | unsigned bucketIndex = getBucketIndex(num); 52 | unsigned bitIndex = getBitIndex(num); 53 | 54 | uint8_t mask = ~(1 << bitIndex); 55 | buckets[bucketIndex] &= mask; 56 | } 57 | 58 | bool Set::contains(unsigned num) const 59 | { 60 | if (num > n) 61 | { 62 | return false; 63 | } 64 | 65 | unsigned bucketIndex = getBucketIndex(num); 66 | unsigned bitIndex = getBitIndex(num); 67 | 68 | uint8_t mask = 1 << bitIndex; 69 | return buckets[bucketIndex] & mask; 70 | } 71 | 72 | void Set::print() const 73 | { 74 | std::cout << "{ "; 75 | for (size_t i = 0; i < n; i++) 76 | { 77 | if (contains(i)) 78 | { 79 | std::cout << i << " "; 80 | } 81 | } 82 | std::cout << "}" << std::endl; 83 | } 84 | 85 | Set unionOfSets(const Set& lhs, const Set& rhs) 86 | { 87 | Set result(std::max(lhs.n, rhs.n)); 88 | 89 | size_t minBucketsCount = std::min(lhs.bucketsCount, rhs.bucketsCount); 90 | for (size_t i = 0; i < minBucketsCount; i++) 91 | { 92 | result.buckets[i] = lhs.buckets[i] | rhs.buckets[i]; 93 | } 94 | 95 | const Set& biggerSet = lhs.bucketsCount > rhs.bucketsCount ? lhs : rhs; 96 | for (size_t i = minBucketsCount; i < biggerSet.bucketsCount; i++) 97 | { 98 | result.buckets[i] = biggerSet.buckets[i]; 99 | } 100 | 101 | return result; 102 | } 103 | 104 | Set intersectionOfSets(const Set& lhs, const Set& rhs) 105 | { 106 | Set result(std::min(lhs.n, rhs.n)); 107 | 108 | size_t minBucketsCount = std::min(lhs.bucketsCount, rhs.bucketsCount); 109 | for (size_t i = 0; i < minBucketsCount; i++) 110 | { 111 | result.buckets[i] = lhs.buckets[i] & rhs.buckets[i]; 112 | } 113 | 114 | return result; 115 | } 116 | 117 | unsigned Set::getBucketIndex(unsigned num) const 118 | { 119 | return num / elementsInBucket; 120 | } 121 | 122 | unsigned Set::getBitIndex(unsigned num) const 123 | { 124 | return num % elementsInBucket; 125 | } 126 | 127 | void Set::copyFrom(const Set& other) 128 | { 129 | buckets = new uint8_t[other.bucketsCount]; 130 | for (size_t i = 0; i < other.bucketsCount; i++) 131 | { 132 | buckets[i] = other.buckets[i]; 133 | } 134 | bucketsCount = other.bucketsCount; 135 | n = other.n; 136 | } 137 | 138 | void Set::free() 139 | { 140 | delete[] buckets; 141 | buckets = nullptr; 142 | bucketsCount = 0; 143 | } 144 | -------------------------------------------------------------------------------- /Sem_06/Big4 examples/Bitset/Set.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class Set 5 | { 6 | public: 7 | Set(unsigned n); 8 | 9 | Set() = default; 10 | Set(const Set& other); 11 | Set& operator=(const Set& other); 12 | ~Set(); 13 | 14 | void add(unsigned num); 15 | void remove(unsigned num); 16 | bool contains(unsigned num) const; 17 | void print() const; 18 | 19 | friend Set unionOfSets(const Set& lhs, const Set& rhs); 20 | friend Set intersectionOfSets(const Set& lhs, const Set& rhs); 21 | 22 | private: 23 | unsigned n = 0; 24 | uint8_t* buckets = nullptr; 25 | size_t bucketsCount = 0; 26 | static constexpr size_t elementsInBucket = sizeof(uint8_t) * 8; 27 | 28 | unsigned getBucketIndex(unsigned num) const; 29 | unsigned getBitIndex(unsigned num) const; 30 | 31 | void copyFrom(const Set& other); 32 | void free(); 33 | }; 34 | -------------------------------------------------------------------------------- /Sem_06/Big4 examples/Bitset/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "Set.h" 2 | 3 | int main() 4 | { 5 | std::cout << "s1: "; 6 | Set s1(1024); 7 | s1.add(1); 8 | s1.add(10); 9 | s1.add(5); 10 | s1.add(22); 11 | s1.add(23); 12 | s1.add(24); 13 | s1.print(); 14 | 15 | std::cout << "s2: "; 16 | Set s2(50); 17 | s2.add(1); 18 | s2.add(17); 19 | s2.add(49); 20 | s2.remove(49); 21 | s2.print(); 22 | 23 | Set unionRes = unionOfSets(s1, s2); 24 | Set intersectionRes = intersectionOfSets(s1, s2); 25 | 26 | std::cout << "union of s1 and s2: "; 27 | unionRes.print(); 28 | std::cout << "intersection of s1 and s2: "; 29 | intersectionRes.print(); 30 | } 31 | -------------------------------------------------------------------------------- /Sem_06/Big4 examples/GPSPath/GPSPath.cpp: -------------------------------------------------------------------------------- 1 | #include "GPSPath.h" 2 | 3 | GPSPath::GPSPath() 4 | { 5 | path = new GPSPath::Point[capacity]; 6 | } 7 | GPSPath::GPSPath(const GPSPath& other) 8 | { 9 | copyFrom(other); 10 | } 11 | GPSPath& GPSPath::operator=(const GPSPath& other) 12 | { 13 | if (this != &other) 14 | { 15 | free(); 16 | copyFrom(other); 17 | } 18 | return *this; 19 | } 20 | GPSPath::~GPSPath() 21 | { 22 | free(); 23 | } 24 | 25 | void GPSPath::addPoint(int x, int y) 26 | { 27 | if (count == capacity) 28 | { 29 | resize(capacity * 2); 30 | } 31 | 32 | Point newPoint{ x, y }; 33 | path[count++] = newPoint; 34 | if (count > 1) 35 | { 36 | pathLength += path[count - 2].getDist(path[count - 1]); 37 | } 38 | } 39 | void GPSPath::changePoint(int x, int y, unsigned index) 40 | { 41 | if (index >= count) 42 | { 43 | return; 44 | } 45 | 46 | const Point& currentPoint = path[index]; 47 | Point newPoint{ x, y }; 48 | 49 | if (index == 0 && count > 1) 50 | { 51 | const Point& nextPoint = path[index + 1]; 52 | float oldDist = currentPoint.getDist(nextPoint); 53 | 54 | (pathLength -= oldDist) += newPoint.getDist(nextPoint); 55 | } 56 | else if (index == count - 1 && count > 1) 57 | { 58 | const Point& prevPoint = path[index - 1]; 59 | float oldDist = currentPoint.getDist(prevPoint); 60 | 61 | (pathLength -= oldDist) += newPoint.getDist(prevPoint); 62 | } 63 | else 64 | { 65 | const Point& prevPoint = path[index - 1]; 66 | float oldDist1 = currentPoint.getDist(prevPoint); 67 | 68 | const Point& nextPoint = path[index + 1]; 69 | float oldDist2 = currentPoint.getDist(nextPoint); 70 | 71 | pathLength -= (oldDist1 + oldDist2); 72 | pathLength += (newPoint.getDist(prevPoint) + newPoint.getDist(nextPoint)); 73 | } 74 | 75 | path[index] = newPoint; 76 | } 77 | 78 | float GPSPath::getDistance() const 79 | { 80 | return pathLength; 81 | } 82 | 83 | void GPSPath::resize(size_t newCapacity) 84 | { 85 | capacity = newCapacity; 86 | 87 | GPSPath::Point* temp = new GPSPath::Point[capacity]; 88 | for (size_t i = 0; i < count; i++) 89 | { 90 | temp[i] = path[i]; 91 | } 92 | 93 | delete[] path; 94 | path = temp; 95 | } 96 | 97 | void GPSPath::copyFrom(const GPSPath& other) 98 | { 99 | capacity = other.capacity; 100 | count = other.count; 101 | 102 | path = new GPSPath::Point[capacity]; 103 | for (size_t i = 0; i < count; i++) 104 | { 105 | path[i] = other.path[i]; 106 | } 107 | 108 | pathLength = other.pathLength; 109 | } 110 | void GPSPath::free() 111 | { 112 | delete[] path; 113 | path = nullptr; 114 | capacity = count = pathLength = 0; 115 | } -------------------------------------------------------------------------------- /Sem_06/Big4 examples/GPSPath/GPSPath.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class GPSPath 5 | { 6 | private: 7 | struct Point 8 | { 9 | int x; 10 | int y; 11 | float getDist(const Point& other) const 12 | { 13 | int dx = x - other.x; 14 | int dy = y - other.y; 15 | return sqrt(dx * dx + dy * dy); 16 | } 17 | }; 18 | 19 | Point* path = nullptr; 20 | size_t capacity = 8; 21 | size_t count = 0; 22 | 23 | float pathLength = 0; 24 | 25 | private: 26 | void resize(size_t newCapacity); 27 | 28 | void copyFrom(const GPSPath& other); 29 | void free(); 30 | 31 | public: 32 | GPSPath(); 33 | GPSPath(const GPSPath& other); 34 | GPSPath& operator=(const GPSPath& other); 35 | ~GPSPath(); 36 | 37 | void addPoint(int x, int y); 38 | void changePoint(int x, int y, unsigned index); 39 | 40 | float getDistance() const; 41 | }; 42 | -------------------------------------------------------------------------------- /Sem_06/Big4 examples/GPSPath/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "GpsPath.h" 2 | #include 3 | 4 | int main() 5 | { 6 | GPSPath p; 7 | 8 | p.addPoint(1, 2); 9 | p.addPoint(1, 4); 10 | p.addPoint(1, 10); 11 | p.changePoint(1, 12, 1); 12 | 13 | std::cout << p.getDistance(); 14 | } -------------------------------------------------------------------------------- /Sem_06/Big4 examples/GraduatedStudent/GraduatedStudent.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class GraduatedStudent 5 | { 6 | public: 7 | GraduatedStudent(const char* name, const unsigned* grades, size_t gradesCount, const char* quote); 8 | 9 | GraduatedStudent() = default; 10 | GraduatedStudent(const GraduatedStudent& other); 11 | GraduatedStudent& operator=(const GraduatedStudent& other); 12 | ~GraduatedStudent(); 13 | 14 | void setName(const char* newName); 15 | void setGrades(const unsigned* newGrades, size_t newGradesCount); 16 | void setQuote(const char* quote); 17 | 18 | const char* name() const; 19 | const unsigned* grades() const; 20 | size_t gradesCount() const; 21 | double averageGrade() const; 22 | const char* quote() const; 23 | 24 | static double averageGradeForAllGraduates(); 25 | static size_t allGraduatesCount(); 26 | 27 | private: 28 | char* m_name = nullptr; 29 | unsigned* m_grades = nullptr; 30 | size_t m_gradesCount = 0; 31 | double m_averageGrade = 0; 32 | 33 | static constexpr size_t m_maxQuoteSize = 32; 34 | char m_quote[m_maxQuoteSize + 1] = ""; 35 | 36 | static double m_averageGradeForAllGraduates; 37 | static size_t m_allGraduatesCount; 38 | 39 | void updateAverageGrade(); 40 | 41 | void copyFrom(const GraduatedStudent& other); 42 | void free(); 43 | }; 44 | -------------------------------------------------------------------------------- /Sem_06/Big4 examples/GraduatedStudent/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "GraduatedStudent.h" 2 | 3 | int main() 4 | { 5 | unsigned grades1[] = { 3, 3, 4, 4, 5, 5 }; 6 | GraduatedStudent gs1("Atanas", grades1, sizeof(grades1) / sizeof(unsigned), "Winning!"); 7 | 8 | std::cout << "Average grade of " << gs1.name() << " is " << gs1.averageGrade() << std::endl; 9 | std::cout << "Average grade for all students is " << GraduatedStudent::averageGradeForAllGraduates() << std::endl << std::endl; 10 | 11 | unsigned grades2[] = { 3, 2, 2, 3 }; 12 | GraduatedStudent gs2("Ivan Angelov", grades2, sizeof(grades2) / sizeof(unsigned), "Losing!"); 13 | 14 | std::cout << "Average grade of " << gs2.name() << " is " << gs2.averageGrade() << std::endl; 15 | std::cout << "Average grade for all students is " << GraduatedStudent::averageGradeForAllGraduates() << std::endl << std::endl; 16 | 17 | unsigned grades3[] = { 6, 6, 6, 6, 6 }; 18 | { 19 | GraduatedStudent gs3("Zahari", grades3, sizeof(grades3) / sizeof(unsigned), "Best of the best!"); 20 | 21 | std::cout << "Average grade of " << gs3.name() << " is " << gs3.averageGrade() << std::endl; 22 | std::cout << "Average grade for all students is " << GraduatedStudent::averageGradeForAllGraduates() << std::endl << std::endl; 23 | } 24 | 25 | std::cout << "Zahari is gone....." << std::endl; 26 | std::cout << "Average grade for all students is " << GraduatedStudent::averageGradeForAllGraduates() << std::endl << std::endl; 27 | 28 | std::cout << "Changing Atanas's grades..." << std::endl; 29 | gs1.setGrades(grades3, sizeof(grades3) / sizeof(unsigned)); 30 | std::cout << "Average grade of " << gs1.name() << " is " << gs1.averageGrade() << std::endl; 31 | std::cout << "Average grade for all students is " << GraduatedStudent::averageGradeForAllGraduates() << std::endl << std::endl; 32 | 33 | GraduatedStudent gs4(gs1); 34 | std::cout << "Average grade of Atanas's copy is " << gs4.averageGrade() << std::endl; 35 | std::cout << "Average grade for all students is " << GraduatedStudent::averageGradeForAllGraduates() << std::endl << std::endl; 36 | 37 | std::cout << "All graduated students are " << GraduatedStudent::allGraduatesCount() << std::endl; 38 | } 39 | -------------------------------------------------------------------------------- /Sem_06/Big4 examples/Person/Person.cpp: -------------------------------------------------------------------------------- 1 | #include "Person.h" 2 | 3 | Person::Person(const char* name, unsigned int age) 4 | { 5 | setName(name); 6 | setAge(age); 7 | } 8 | 9 | Person::Person(const Person& other) 10 | { 11 | copyFrom(other); 12 | } 13 | Person& Person::operator=(const Person& other) 14 | { 15 | if (this != &other) 16 | { 17 | free(); 18 | copyFrom(other); 19 | } 20 | return *this; 21 | } 22 | Person::~Person() 23 | { 24 | free(); 25 | } 26 | 27 | void Person::setName(const char* name) 28 | { 29 | if (name == nullptr || this->name == name) 30 | { 31 | return; 32 | } 33 | delete[] this->name; 34 | this->name = new char[strlen(name) + 1]; 35 | strcpy(this->name, name); 36 | } 37 | void Person::setAge(unsigned int age) 38 | { 39 | this->age = age; 40 | } 41 | 42 | const char* Person::getName() const 43 | { 44 | return name; 45 | } 46 | unsigned int Person::getAge() const 47 | { 48 | return age; 49 | } 50 | 51 | void Person::print() const 52 | { 53 | std::cout << "Name: " << name << ", Age: " << age << std::endl; 54 | } 55 | 56 | void Person::copyFrom(const Person& other) 57 | { 58 | name = new char[strlen(other.name) + 1]; 59 | strcpy(name, other.name); 60 | age = other.age; 61 | } 62 | void Person::free() 63 | { 64 | delete[] name; 65 | name = nullptr; 66 | } -------------------------------------------------------------------------------- /Sem_06/Big4 examples/Person/Person.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma warning (disable : 4996) 3 | #include 4 | 5 | class Person 6 | { 7 | private: 8 | char* name = nullptr; 9 | unsigned int age; 10 | 11 | void copyFrom(const Person& other); 12 | void free(); 13 | 14 | public: 15 | Person(const char* name, unsigned int age); 16 | 17 | // Big 4 18 | Person() = default; 19 | Person(const Person& other); 20 | Person& operator=(const Person& other); 21 | ~Person(); 22 | 23 | void setName(const char* name); 24 | void setAge(unsigned int age); 25 | 26 | const char* getName() const; 27 | unsigned int getAge() const; 28 | 29 | void print() const; 30 | }; 31 | -------------------------------------------------------------------------------- /Sem_06/Big4 examples/Person/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "Person.h" 2 | 3 | int main() 4 | { 5 | Person p1("Robert", 35); 6 | Person p2(p1); // Copy constructor 7 | Person p3("George", 26); 8 | Person p4 = p3; // Copy constructor 9 | p4 = p1; // Operator= 10 | 11 | p1.print(); 12 | p2.print(); 13 | p3.print(); 14 | p4.print(); 15 | } -------------------------------------------------------------------------------- /Sem_06/Static examples/Fibonacci_static_cache/MapKeys0toN.cpp: -------------------------------------------------------------------------------- 1 | #include "MapKeys0toN.h" 2 | #include 3 | 4 | void MapKeys0toN::add(unsigned key, unsigned value) 5 | { 6 | if (value == 0) 7 | { 8 | return; 9 | } 10 | values[key] = value; 11 | } 12 | 13 | bool MapKeys0toN::contains(unsigned key) const 14 | { 15 | return values[key] != 0; 16 | } 17 | 18 | unsigned MapKeys0toN::getValue(unsigned key) const 19 | { 20 | if (!contains(key)) 21 | { 22 | throw std::invalid_argument("Map does not contain the provided key"); 23 | } 24 | return values[key]; 25 | } -------------------------------------------------------------------------------- /Sem_06/Static examples/Fibonacci_static_cache/MapKeys0toN.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class MapKeys0toN 5 | { 6 | public: 7 | void add(unsigned key, unsigned value); 8 | bool contains(unsigned key) const; 9 | unsigned getValue(unsigned key) const; 10 | 11 | private: 12 | static constexpr size_t n = 100; 13 | unsigned values[n]{ 0 }; 14 | }; -------------------------------------------------------------------------------- /Sem_06/Static examples/Fibonacci_static_cache/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "MapKeys0toN.h" 2 | 3 | unsigned long long fib(unsigned n) 4 | { 5 | if (n <= 2) 6 | { 7 | return 1; 8 | } 9 | 10 | static MapKeys0toN cache; 11 | 12 | if (cache.contains(n)) 13 | { 14 | return cache.getValue(n); 15 | } 16 | 17 | unsigned long long res = fib(n - 1) + fib(n - 2); 18 | cache.add(n, res); 19 | return res; 20 | } 21 | 22 | int main() 23 | { 24 | std::cout << fib(30) << std::endl; 25 | std::cout << fib(30) << std::endl; 26 | } -------------------------------------------------------------------------------- /Sem_06/Static examples/ObjectCounter/ObjectCounter.cpp: -------------------------------------------------------------------------------- 1 | #include "ObjectCounter.h" 2 | 3 | unsigned ObjectCounter::nextId = 1; 4 | unsigned ObjectCounter::count = 0; 5 | 6 | ObjectCounter::ObjectCounter() 7 | { 8 | ++count; 9 | currentObjectId = nextId; 10 | nextId += Idstep; 11 | } 12 | ObjectCounter::~ObjectCounter() 13 | { 14 | --count; 15 | } 16 | 17 | unsigned ObjectCounter::getId() const 18 | { 19 | return currentObjectId; 20 | } 21 | unsigned ObjectCounter::getObjectCount() 22 | { 23 | return count; 24 | } 25 | -------------------------------------------------------------------------------- /Sem_06/Static examples/ObjectCounter/ObjectCounter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | class ObjectCounter 4 | { 5 | public: 6 | ObjectCounter(); 7 | ~ObjectCounter(); 8 | 9 | unsigned getId() const; 10 | static unsigned getObjectCount(); 11 | 12 | private: 13 | unsigned currentObjectId; 14 | static unsigned nextId; 15 | const static unsigned Idstep = 1; 16 | 17 | static unsigned count; 18 | }; 19 | -------------------------------------------------------------------------------- /Sem_06/Static examples/ObjectCounter/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "ObjectCounter.h" 2 | #include 3 | 4 | int main() 5 | { 6 | ObjectCounter obj1; 7 | ObjectCounter obj2; 8 | ObjectCounter obj3; 9 | 10 | { 11 | ObjectCounter obj4; 12 | ObjectCounter obj5; 13 | std::cout << "Current number of objects is: " << ObjectCounter::getObjectCount() << std::endl; 14 | } 15 | std::cout << "Current number of objects is: " << ObjectCounter::getObjectCount() << std::endl; 16 | } -------------------------------------------------------------------------------- /Sem_06/images/Constr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_06/images/Constr.png -------------------------------------------------------------------------------- /Sem_06/images/CopyConstr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_06/images/CopyConstr.png -------------------------------------------------------------------------------- /Sem_06/images/Destr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_06/images/Destr.png -------------------------------------------------------------------------------- /Sem_06/images/RealCopy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_06/images/RealCopy.png -------------------------------------------------------------------------------- /Sem_06/images/ShallowCopy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_06/images/ShallowCopy.png -------------------------------------------------------------------------------- /Sem_07/FlightsScanner/FlightsScanner.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class FlightsScanner 5 | { 6 | public: 7 | FlightsScanner(const char* inputFileName, const char* outputFileName); 8 | void run(); 9 | 10 | private: 11 | struct FlightRecord 12 | { 13 | static constexpr size_t airportCodeSize = 3; 14 | char origin[airportCodeSize + 1]; 15 | char dest[airportCodeSize + 1]; 16 | unsigned int amount; 17 | }; 18 | 19 | static constexpr size_t maxFileNameSize = 32; 20 | char inputFileName[maxFileNameSize + 1] = ""; 21 | char outputFileName[maxFileNameSize + 1] = ""; 22 | 23 | void handleAirportCode(char* airportCode) const; 24 | void parseLine(const char* line, FlightRecord& record) const; 25 | 26 | void saveRecord(std::ofstream& ofs, const FlightRecord& record) const; 27 | bool readAndExportData(std::ifstream& ifs) const; 28 | }; 29 | -------------------------------------------------------------------------------- /Sem_07/FlightsScanner/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "FlightsScanner.h" 2 | 3 | int main() 4 | { 5 | FlightsScanner scanner("inputFlights.txt", "outputFlights.txt"); 6 | scanner.run(); 7 | } -------------------------------------------------------------------------------- /Sem_07/FlightsScanner/Utils.cpp: -------------------------------------------------------------------------------- 1 | #include "Utils.h" 2 | #include 3 | 4 | bool isLower(char ch) 5 | { 6 | return ch >= 'a' && ch <= 'z'; 7 | } 8 | 9 | bool isSymbol(char ch) 10 | { 11 | return ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z'; 12 | } 13 | 14 | void toUpper(char* str) 15 | { 16 | if (str == nullptr) 17 | { 18 | throw std::invalid_argument("The given string does not exist"); 19 | } 20 | 21 | int diff = 'a' - 'A'; 22 | while (*str) 23 | { 24 | if (!isSymbol(*str)) 25 | { 26 | throw std::bad_cast(); 27 | } 28 | if (isLower(*str)) 29 | { 30 | *str = *str - diff; 31 | } 32 | str++; 33 | } 34 | } 35 | 36 | unsigned int charToDigit(char ch) 37 | { 38 | if (ch < '0' || ch > '9') 39 | { 40 | throw std::bad_cast(); 41 | } 42 | return ch - '0'; 43 | } 44 | 45 | unsigned int strToNumber(const char* str) 46 | { 47 | if (!str) 48 | { 49 | throw std::invalid_argument("The given string does not exist"); 50 | } 51 | 52 | unsigned int result = 0; 53 | while (*str) 54 | { 55 | result *= 10; 56 | result += charToDigit(*str); 57 | str++; 58 | } 59 | return result; 60 | } -------------------------------------------------------------------------------- /Sem_07/FlightsScanner/Utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | bool isLower(char ch); 4 | bool isSymbol(char ch); 5 | void toUpper(char* str); 6 | unsigned int charToDigit(char ch); 7 | unsigned int strToNumber(const char* str); -------------------------------------------------------------------------------- /Sem_07/FlightsScanner/inputFlights.txt: -------------------------------------------------------------------------------- 1 | SoF vAr 70 2 | fra LHR 115 3 | paris rome 82 4 | CDG FCO 16s 5 | MXp nCE 86 6 | MXp NICE 86 7 | airport -------------------------------------------------------------------------------- /Sem_07/images/StackUnwinding.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_07/images/StackUnwinding.png -------------------------------------------------------------------------------- /Sem_08/1. ComplexNumber/ComplexNumber.cpp: -------------------------------------------------------------------------------- 1 | #include "ComplexNumber.h" 2 | 3 | ComplexNumber::ComplexNumber(double real, double im) 4 | { 5 | this->real = real; 6 | this->im = im; 7 | } 8 | 9 | ComplexNumber ComplexNumber::getComplexConjugate() const 10 | { 11 | ComplexNumber complexConjugate(real, (-1)*im); 12 | return complexConjugate; 13 | } 14 | 15 | void ComplexNumber::setReal(double real) 16 | { 17 | this->real = real; 18 | } 19 | void ComplexNumber::setIm(double im) 20 | { 21 | this->im = im; 22 | } 23 | 24 | double ComplexNumber::getReal() const 25 | { 26 | return real; 27 | } 28 | double ComplexNumber::getIm() const 29 | { 30 | return im; 31 | } 32 | 33 | ComplexNumber& ComplexNumber::operator+=(const ComplexNumber& other) 34 | { 35 | real += other.real; 36 | im += other.im; 37 | return *this; 38 | } 39 | ComplexNumber& ComplexNumber::operator-=(const ComplexNumber& other) 40 | { 41 | real -= other.real; 42 | im -= other.im; 43 | return *this; 44 | } 45 | ComplexNumber& ComplexNumber::operator*=(const ComplexNumber& other) 46 | { 47 | double originalReal = real; 48 | real = real * other.real - im * other.im; 49 | im = originalReal * other.im + im * other.real; 50 | return *this; 51 | } 52 | ComplexNumber& ComplexNumber::operator/=(const ComplexNumber& other) 53 | { 54 | ComplexNumber complexConjugate = other.getComplexConjugate(); 55 | ComplexNumber otherCopy(other); 56 | 57 | *this *= complexConjugate; 58 | otherCopy *= complexConjugate; 59 | 60 | if (otherCopy.real) // To avoid division by zero. 61 | { 62 | real /= otherCopy.real; 63 | im /= otherCopy.real; 64 | } 65 | 66 | return *this; 67 | } 68 | 69 | ComplexNumber operator+(const ComplexNumber& lhs, const ComplexNumber& rhs) 70 | { 71 | ComplexNumber result(lhs); 72 | result += rhs; 73 | return result; 74 | } 75 | ComplexNumber operator-(const ComplexNumber& lhs, const ComplexNumber& rhs) 76 | { 77 | ComplexNumber result(lhs); 78 | result -= rhs; 79 | return result; 80 | } 81 | ComplexNumber operator*(const ComplexNumber& lhs, const ComplexNumber& rhs) 82 | { 83 | ComplexNumber result(lhs); 84 | result *= rhs; 85 | return result; 86 | } 87 | ComplexNumber operator/(const ComplexNumber& lhs, const ComplexNumber& rhs) 88 | { 89 | ComplexNumber result(lhs); 90 | result /= rhs; 91 | return result; 92 | } 93 | 94 | bool operator==(const ComplexNumber& lhs, const ComplexNumber& rhs) 95 | { 96 | return lhs.getReal() == rhs.getReal() && lhs.getIm() == rhs.getIm(); 97 | } 98 | bool operator!=(const ComplexNumber& lhs, const ComplexNumber& rhs) 99 | { 100 | return !(lhs == rhs); 101 | } 102 | 103 | std::ostream& operator<<(std::ostream& os, const ComplexNumber& cN) 104 | { 105 | return os << cN.real << " + i" << cN.im; 106 | } 107 | std::istream& operator>>(std::istream& is, ComplexNumber& cN) 108 | { 109 | return is >> cN.real >> cN.im; 110 | } 111 | -------------------------------------------------------------------------------- /Sem_08/1. ComplexNumber/ComplexNumber.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class ComplexNumber 5 | { 6 | private: 7 | double real = 0; 8 | double im = 0; 9 | 10 | public: 11 | ComplexNumber(double real, double im); 12 | 13 | ComplexNumber getComplexConjugate() const; 14 | 15 | void setReal(double real); 16 | void setIm(double im); 17 | 18 | double getReal() const; 19 | double getIm() const; 20 | 21 | ComplexNumber& operator+=(const ComplexNumber&); 22 | ComplexNumber& operator-=(const ComplexNumber&); 23 | ComplexNumber& operator*=(const ComplexNumber&); 24 | ComplexNumber& operator/=(const ComplexNumber&); 25 | 26 | // These should be friend functions because they are binary functions and their first arguments are NOT objects of our class ComplexNumber. 27 | friend std::ostream& operator<<(std::ostream&, const ComplexNumber&); 28 | friend std::istream& operator>>(std::istream&, ComplexNumber&); 29 | }; 30 | 31 | ComplexNumber operator+(const ComplexNumber&, const ComplexNumber&); 32 | ComplexNumber operator-(const ComplexNumber&, const ComplexNumber&); 33 | ComplexNumber operator*(const ComplexNumber&, const ComplexNumber&); 34 | ComplexNumber operator/(const ComplexNumber&, const ComplexNumber&); 35 | 36 | bool operator==(const ComplexNumber&, const ComplexNumber&); 37 | bool operator!=(const ComplexNumber&, const ComplexNumber&); 38 | -------------------------------------------------------------------------------- /Sem_08/1. ComplexNumber/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "ComplexNumber.h" 2 | 3 | int main() 4 | { 5 | ComplexNumber c1(10, 13); 6 | ComplexNumber c2(18, 7); 7 | 8 | std::cout << c1 / c2; 9 | } -------------------------------------------------------------------------------- /Sem_08/2. NVector/NVector.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class NVector 5 | { 6 | private: 7 | int* data; 8 | size_t size; 9 | 10 | void copyFrom(const NVector& other); 11 | void free(); 12 | 13 | public: 14 | NVector(size_t size); 15 | NVector(const NVector& other); 16 | NVector& operator=(const NVector& other); 17 | ~NVector(); 18 | 19 | size_t getSize() const; 20 | 21 | NVector& operator+=(const NVector& other); 22 | NVector& operator-=(const NVector& other); 23 | 24 | NVector& operator*=(size_t scalar); 25 | 26 | int& operator[](size_t index); 27 | int operator[](size_t index) const; 28 | 29 | friend std::ostream& operator<<(std::ostream& os, const NVector& v); 30 | friend std::istream& operator>>(std::istream& is, NVector& v); 31 | }; 32 | 33 | NVector operator+(const NVector& lhs, const NVector& rhs); 34 | NVector operator-(const NVector& lhs, const NVector& rhs); 35 | 36 | //So it could be commutative 37 | NVector operator*(const NVector& v, size_t scalar); 38 | NVector operator*(size_t scalar, const NVector& v); 39 | 40 | //are parallel 41 | bool operator||(const NVector& lhs, const NVector& rhs); 42 | 43 | //are perpendicular 44 | bool operator|=(const NVector& lhs, const NVector& rhs); -------------------------------------------------------------------------------- /Sem_08/2. NVector/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "NVector.h" 2 | #include 3 | 4 | int main() 5 | { 6 | try 7 | { 8 | NVector v1(3), v2(3); 9 | for (size_t i = 0; i < v1.getSize(); i++) 10 | { 11 | v1[i] = v2[i] = i; 12 | } 13 | 14 | NVector v3 = v1 + v2; 15 | std::cout << v3; 16 | } 17 | catch (const std::exception& e) 18 | { 19 | std::cout << "Error: " << e.what() << std::endl; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Sem_08/3. MyString/MyString.cpp: -------------------------------------------------------------------------------- 1 | #include "MyString.h" 2 | #include 3 | #include 4 | #include 5 | 6 | #pragma warning (disable : 4996) 7 | 8 | void MyString::concat(const MyString& other) 9 | { 10 | if (!str || !other.str) 11 | { 12 | throw std::logic_error("Null strings can't be concatenated"); 13 | } 14 | 15 | char* temp = new char[size + other.size + 1]; 16 | strcpy(temp, str); 17 | strcat(temp, other.str); 18 | 19 | free(); 20 | str = temp; 21 | size += other.size; 22 | } 23 | 24 | const char* MyString::c_str() const 25 | { 26 | return str; 27 | } 28 | 29 | size_t MyString::getSize() const 30 | { 31 | return size; 32 | } 33 | 34 | MyString& MyString::operator+=(const MyString& other) 35 | { 36 | concat(other); 37 | return *this; 38 | } 39 | 40 | std::ostream& operator<<(std::ostream& os, const MyString& str) 41 | { 42 | return os << str.str; 43 | } 44 | std::istream& operator>>(std::istream& is, MyString& str) 45 | { 46 | char buff[1024]; 47 | is >> std::setw(1024) >> buff; 48 | size_t len = strlen(buff); 49 | 50 | delete[] str.str; 51 | str.str = new char[len + 1]; 52 | strcpy(str.str, buff); 53 | 54 | return is; 55 | } 56 | 57 | MyString operator+(const MyString& lhs, const MyString& rhs) 58 | { 59 | MyString lhsCopy(lhs); 60 | lhsCopy += rhs; 61 | return lhsCopy; 62 | } 63 | 64 | bool operator==(const MyString& lhs, const MyString& rhs) 65 | { 66 | if (!lhs.c_str() || !rhs.c_str()) 67 | { 68 | throw std::logic_error("Null strings can't be compared"); 69 | } 70 | return strcmp(lhs.c_str(), rhs.c_str()) == 0; 71 | } 72 | bool operator<(const MyString& lhs, const MyString& rhs) 73 | { 74 | if (!lhs.c_str() || !rhs.c_str()) 75 | { 76 | throw std::logic_error("Null strings can't be compared"); 77 | } 78 | return strcmp(lhs.c_str(), rhs.c_str()) < 0; 79 | } 80 | bool operator>(const MyString& lhs, const MyString& rhs) 81 | { 82 | if (!lhs.c_str() || !rhs.c_str()) 83 | { 84 | throw std::logic_error("Null strings can't be compared"); 85 | } 86 | return strcmp(lhs.c_str(), rhs.c_str()) > 0; 87 | } 88 | 89 | MyString::MyString(const char* str) 90 | { 91 | if (str == nullptr || this->str == str) 92 | { 93 | throw std::invalid_argument("Invalid parameter!"); 94 | } 95 | 96 | size_t len = strlen(str); 97 | this->str = new char[len + 1]; 98 | strcpy(this->str, str); 99 | size = len; 100 | } 101 | 102 | MyString::MyString(const MyString& other) 103 | { 104 | copyFrom(other); 105 | } 106 | MyString& MyString::operator=(const MyString& other) 107 | { 108 | if (this != &other) 109 | { 110 | free(); 111 | copyFrom(other); 112 | } 113 | return *this; 114 | } 115 | MyString::~MyString() 116 | { 117 | free(); 118 | } 119 | 120 | void MyString::copyFrom(const MyString& other) 121 | { 122 | str = new char[strlen(other.str) + 1]; 123 | strcpy(str, other.str); 124 | size = other.size; 125 | } 126 | void MyString::free() 127 | { 128 | delete[] str; 129 | } 130 | -------------------------------------------------------------------------------- /Sem_08/3. MyString/MyString.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class MyString 5 | { 6 | private: 7 | char* str = nullptr; 8 | size_t size = 0; 9 | 10 | void copyFrom(const MyString& other); 11 | void free(); 12 | 13 | public: 14 | MyString(const char* str); 15 | 16 | MyString() = default; 17 | MyString(const MyString& other); 18 | MyString& operator=(const MyString& other); 19 | ~MyString(); 20 | 21 | void concat(const MyString& other); 22 | 23 | const char* c_str() const; 24 | 25 | size_t getSize() const; 26 | 27 | MyString& operator+=(const MyString& other); 28 | 29 | friend std::ostream& operator<<(std::ostream& os, const MyString& str); 30 | friend std::istream& operator>>(std::istream& is, MyString& str); 31 | }; 32 | 33 | MyString operator+(const MyString& lhs, const MyString& rhs); 34 | 35 | bool operator==(const MyString& lhs, const MyString& rhs); 36 | bool operator<(const MyString& lhs, const MyString& rhs); 37 | bool operator>(const MyString& lhs, const MyString& rhs); 38 | -------------------------------------------------------------------------------- /Sem_08/3. MyString/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "MyString.h" 2 | 3 | int main() 4 | { 5 | try 6 | { 7 | MyString str1("OOP"); 8 | MyString str2(" is great!"); 9 | str1 += str2; 10 | 11 | std::cout << str1 << std::endl; 12 | } 13 | catch (const std::exception& e) 14 | { 15 | std::cout << "Error: " << e.what() << std::endl; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Sem_08/images/Operators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_08/images/Operators.png -------------------------------------------------------------------------------- /Sem_08/images/OperatorsPrecedence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_08/images/OperatorsPrecedence.png -------------------------------------------------------------------------------- /Sem_09/DynamicArrayOfPointers/DynamicArrayOfPointers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | struct A 5 | { 6 | int x = 5; 7 | int y = 23; 8 | }; 9 | 10 | class DynamicArrayOfPointers 11 | { 12 | public: 13 | DynamicArrayOfPointers(); 14 | DynamicArrayOfPointers(const DynamicArrayOfPointers& other); 15 | DynamicArrayOfPointers(DynamicArrayOfPointers&& other) noexcept; 16 | 17 | DynamicArrayOfPointers& operator=(const DynamicArrayOfPointers& other); 18 | DynamicArrayOfPointers& operator=(DynamicArrayOfPointers&& other) noexcept; 19 | 20 | ~DynamicArrayOfPointers(); 21 | 22 | size_t size() const; 23 | 24 | void addAtFirstFreeIndex(const A& el); 25 | void addAtFirstFreeIndex(A&& el); 26 | 27 | void removeAt(unsigned index); 28 | 29 | bool contains(unsigned index) const; 30 | 31 | void setAtIndex(const A& obj, unsigned index); 32 | void setAtIndex(A&& obj, unsigned index); 33 | 34 | const A& operator[](unsigned index) const; 35 | A& operator[](unsigned index); 36 | 37 | private: 38 | A** data; 39 | size_t capacity; 40 | size_t count; 41 | 42 | void copyFrom(const DynamicArrayOfPointers& other); 43 | void moveFrom(DynamicArrayOfPointers&& other); 44 | 45 | void free(); 46 | 47 | void resize(size_t newCapacity); 48 | 49 | int getFirstFreeIndex() const; // not optimal 50 | }; 51 | -------------------------------------------------------------------------------- /Sem_09/DynamicArrayOfPointers/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "DynamicArrayOfPointers.h" 2 | 3 | int main() 4 | { 5 | DynamicArrayOfPointers dA; 6 | 7 | A obj1{ 5, 23 }; 8 | A obj2{ 22, 24 }; 9 | 10 | dA.addAtFirstFreeIndex(obj1); 11 | dA.addAtFirstFreeIndex(obj2); 12 | 13 | std::cout << dA[0].x; 14 | } -------------------------------------------------------------------------------- /Sem_09/MyString (with move)/MyString.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class MyString 5 | { 6 | private: 7 | char* str = nullptr; 8 | size_t size = 0; 9 | 10 | void copyFrom(const MyString& other); 11 | void moveFrom(MyString&& other); 12 | 13 | void free(); 14 | 15 | public: 16 | MyString(const char* str); 17 | 18 | MyString() = default; 19 | 20 | MyString(const MyString& other); 21 | MyString(MyString&& other) noexcept; 22 | 23 | MyString& operator=(const MyString& other); 24 | MyString& operator=(MyString&& other) noexcept; 25 | 26 | ~MyString(); 27 | 28 | void concat(const MyString& other); 29 | 30 | const char* c_str() const; 31 | 32 | size_t getSize() const; 33 | 34 | MyString& operator+=(const MyString& other); 35 | 36 | friend std::ostream& operator<<(std::ostream& os, const MyString& str); 37 | friend std::istream& operator>>(std::istream& is, MyString& str); 38 | }; 39 | 40 | MyString operator+(const MyString& lhs, const MyString& rhs); 41 | 42 | bool operator==(const MyString& lhs, const MyString& rhs); 43 | bool operator<(const MyString& lhs, const MyString& rhs); 44 | bool operator>(const MyString& lhs, const MyString& rhs); -------------------------------------------------------------------------------- /Sem_09/MyString (with move)/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "MyString.h" 2 | 3 | MyString createString(const char* str) 4 | { 5 | MyString createdString(str); 6 | return createdString; 7 | } 8 | 9 | int main() 10 | { 11 | MyString str("Algebra"); 12 | str = createString("OOP"); 13 | } -------------------------------------------------------------------------------- /Sem_09/README.md: -------------------------------------------------------------------------------- 1 | ## Масиви от указатели към обекти 2 | 3 | ![alt_text](https://github.com/MariaGrozdeva/Object-oriented_programming_FMI/blob/main/Sem_09/images/ArrayOfPointers.png) 4 | 5 | **Задача:** Да се реализира клас SortedStringPool, представляващ сортирана колекция от низове с ограничена дължина (< 64). Класът трябва да съдържа методи за добавяне, премахване и търсене на дума като търсенето трябва да бъде с логаритмична сложност. 6 | 7 | --- 8 | 9 | # Move семантики 10 | 11 | ### lvalue и rvalue 12 | 13 | **lvalue** – обект, който заема някакво конкретно място в паметта. 14 | **rvalue** – временен обект (някакъв израз) с временен адрес (регистър). Унищожава се "почти веднага" след като е създаден (в края на израза, в който е бил създаден). 15 | 16 | **&** – за **lvalue** 17 | **Пример:** 18 | ```c++ 19 | #include 20 | 21 | bool f(int& n) 22 | { 23 | return n % 2 == 0; 24 | } 25 | int main() 26 | { 27 | int n = 10; 28 | f(n); // OK! n is lvalue 29 | f(5); // Error! 5 is not an lvalue 30 | } 31 | ``` 32 | 33 | **&&** – за **rvalue** 34 | **Пример:** 35 | ```c++ 36 | bool f(int&& n) 37 | { 38 | return n % 2 == 0; 39 | } 40 | int main() 41 | { 42 | int n = 10; 43 | f(n); // Error! n is not an rvalue 44 | f(5); // OK! 5 is rvalue 45 | } 46 | ``` 47 | 48 | Да разгледаме следния програмен фрагмент: 49 | ```c++ 50 | MyString createString(const char* str) 51 | { 52 | MyString createdString(str); 53 | return createdString; 54 | } 55 | 56 | int main() 57 | { 58 | MyString str("Algebra"); 59 | str = createString("OOP"); 60 | } 61 | ``` 62 | Резултат от изпълнението: 63 | 64 | ![alt_text](https://github.com/MariaGrozdeva/Object-oriented_programming_FMI/blob/main/Sem_09/images/WithoutMove.png) 65 | 66 | **Проблем:** Правим излишни копия :bangbang: Обектът, създаден в createString **се копира два пъти преди да се присвои** на str. 67 | 68 | ## Move конструктор и move оператор= 69 | ```c++ 70 | MyString::MyString(MyString&& other) noexcept 71 | { 72 | str = other.str; 73 | size = other.size; 74 | other.str = nullptr; 75 | other.size = 0; 76 | } 77 | 78 | MyString& MyString::operator=(MyString&& other) noexcept 79 | { 80 | if (this != &other) 81 | { 82 | free(); 83 | 84 | str = other.str; 85 | size = other.size; 86 | other.str = nullptr; 87 | other.size = 0; 88 | } 89 | return *this; 90 | } 91 | ``` 92 | Резултат от изпълнението на по- горния програмен фрагмент: 93 | 94 | ![alt_text](https://github.com/MariaGrozdeva/Object-oriented_programming_FMI/blob/main/Sem_09/images/WithMove.png) 95 | 96 | --- 97 | 98 | ### Важно ❗ 99 | Всъщност, резултатът от изпълнението на фрагмента най- вероятно няма да бъде нито един от посочените, а ще бъде: 100 | 101 | ![alt_text](https://github.com/MariaGrozdeva/Object-oriented_programming_FMI/blob/main/Sem_09/images/RVO.png) 102 | 103 | Това се дължи на оптимизация на компилаторите, наречена **return value optimization (RVO)**. 104 | https://en.cppreference.com/w/cpp/language/copy_elision 105 | 106 | --- 107 | 108 | Допълнителни материали: 109 | https://en.cppreference.com/w/cpp/language/value_category 110 | https://www.internalpointers.com/post/understanding-meaning-lvalues-and-rvalues-c 111 | https://www.internalpointers.com/post/c-rvalue-references-and-move-semantics-beginners 112 | -------------------------------------------------------------------------------- /Sem_09/SortedStringPool/SortedStringPool.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #pragma warning (disable : 4996) 6 | 7 | class SortedStringPool 8 | { 9 | private: 10 | const static size_t maxStringSize = 64; 11 | struct String 12 | { 13 | char str[maxStringSize] = ""; 14 | unsigned int refCount = 0; 15 | 16 | String(const char* str) 17 | { 18 | if (strlen(str) > maxStringSize) 19 | { 20 | throw std::invalid_argument("The length of the argument is longer than the max size"); 21 | } 22 | strcpy(this->str, str); 23 | } 24 | }; 25 | 26 | String** data; 27 | size_t size = 0; 28 | size_t capacity = 4; 29 | 30 | void copyFrom(const SortedStringPool& other); 31 | void free(); 32 | 33 | void resize(size_t newCapacity); 34 | 35 | public: 36 | SortedStringPool(); 37 | SortedStringPool(const SortedStringPool& other); 38 | SortedStringPool& operator=(const SortedStringPool& other); 39 | ~SortedStringPool(); 40 | 41 | bool add(const char* str); 42 | bool removeAt(unsigned int index); 43 | int contains(const char* str) const; // returns the index of the first occurrence of str or -1 if it doesn't exist 44 | 45 | const char* operator[](unsigned int index) const; 46 | 47 | friend std::ostream& operator<<(std::ostream& os, const SortedStringPool& pool); 48 | }; -------------------------------------------------------------------------------- /Sem_09/SortedStringPool/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "SortedStringPool.h" 2 | 3 | int main() 4 | { 5 | SortedStringPool pool; 6 | 7 | pool.add("aaa"); 8 | pool.add("bbb"); 9 | pool.add("ccc"); 10 | std::cout << pool << std::endl << std::endl; 11 | 12 | pool.add("ab"); 13 | pool.add("bc"); 14 | std::cout << pool << std::endl << std::endl; 15 | 16 | pool.add("aaa"); 17 | std::cout << "After adding one more \"aaa\": " << pool << std::endl << std::endl; 18 | 19 | std::cout << "Index of \"aaa\": " << pool.contains("aaa") << std::endl << std::endl; 20 | 21 | pool.removeAt(0); 22 | std::cout << "After removing \"aaa\": " << pool << std::endl << std::endl; 23 | 24 | std::cout << "Index of \"aaa\": " << pool.contains("aaa") << std::endl << std::endl; 25 | 26 | pool.removeAt(0); 27 | std::cout << "After removing \"aaa\": " << pool << std::endl << std::endl; 28 | 29 | std::cout << "Index of \"aaa\": " << pool.contains("aaa") << std::endl << std::endl; 30 | } -------------------------------------------------------------------------------- /Sem_09/UniquePtr/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "UniquePtrOfA.h" 2 | #include 3 | 4 | void print(const UniquePtrOfA& ptr) 5 | { 6 | std::cout << (*ptr).a << " " << (*ptr).b << std::endl; 7 | } 8 | 9 | int main() 10 | { 11 | UniquePtrOfA ptr(new A()); 12 | UniquePtrOfA other(std::move(ptr)); 13 | print(other); 14 | std::cout << other->a << std::endl; 15 | } 16 | -------------------------------------------------------------------------------- /Sem_09/UniquePtr/UniquePtrOfA.cpp: -------------------------------------------------------------------------------- 1 | #include "UniquePtrOfA.h" 2 | 3 | UniquePtrOfA::UniquePtrOfA(A* ptr) : ptr(ptr) 4 | {} 5 | 6 | UniquePtrOfA::UniquePtrOfA(UniquePtrOfA&& other) noexcept 7 | { 8 | ptr = other.ptr; 9 | other.ptr = nullptr; 10 | } 11 | 12 | UniquePtrOfA& UniquePtrOfA::operator=(UniquePtrOfA&& other) noexcept 13 | { 14 | if (this != &other) 15 | { 16 | delete ptr; 17 | ptr = other.ptr; 18 | other.ptr = nullptr; 19 | } 20 | return *this; 21 | } 22 | 23 | UniquePtrOfA::~UniquePtrOfA() 24 | { 25 | delete ptr; 26 | } 27 | 28 | A& UniquePtrOfA::operator*() 29 | { 30 | return *ptr; 31 | } 32 | 33 | const A& UniquePtrOfA::operator*() const 34 | { 35 | return *ptr; 36 | } 37 | 38 | A* UniquePtrOfA::operator->() 39 | { 40 | return ptr; 41 | } 42 | 43 | const A* UniquePtrOfA::operator->() const 44 | { 45 | return ptr; 46 | } 47 | -------------------------------------------------------------------------------- /Sem_09/UniquePtr/UniquePtrOfA.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct A 4 | { 5 | int a = 5; 6 | int b = 23; 7 | }; 8 | 9 | class UniquePtrOfA 10 | { 11 | public: 12 | UniquePtrOfA(A* ptr); 13 | 14 | UniquePtrOfA(const UniquePtrOfA&) = delete; 15 | UniquePtrOfA& operator=(const UniquePtrOfA&) = delete; 16 | 17 | UniquePtrOfA(UniquePtrOfA&&) noexcept; 18 | UniquePtrOfA& operator=(UniquePtrOfA&&) noexcept; 19 | 20 | ~UniquePtrOfA(); 21 | 22 | A& operator*(); 23 | const A& operator*() const; 24 | 25 | A* operator->(); 26 | const A* operator->() const; 27 | 28 | private: 29 | A* ptr; 30 | }; -------------------------------------------------------------------------------- /Sem_09/images/ArrayOfPointers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_09/images/ArrayOfPointers.png -------------------------------------------------------------------------------- /Sem_09/images/RVO.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_09/images/RVO.png -------------------------------------------------------------------------------- /Sem_09/images/WithMove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_09/images/WithMove.png -------------------------------------------------------------------------------- /Sem_09/images/WithoutMove.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_09/images/WithoutMove.png -------------------------------------------------------------------------------- /Sem_10/InheritanceExample/Person/Person.cpp: -------------------------------------------------------------------------------- 1 | #include "Person.h" 2 | 3 | Person::Person(const char* name, unsigned int age) 4 | { 5 | setName(name); 6 | setAge(age); 7 | } 8 | 9 | Person::Person(const Person& other) 10 | { 11 | copyFrom(other); 12 | } 13 | Person& Person::operator=(const Person& other) 14 | { 15 | if (this != &other) 16 | { 17 | free(); 18 | copyFrom(other); 19 | } 20 | return *this; 21 | } 22 | Person::~Person() 23 | { 24 | free(); 25 | } 26 | 27 | void Person::setName(const char* name) 28 | { 29 | if (name == nullptr || this->name == name) 30 | { 31 | return; 32 | } 33 | delete[] this->name; 34 | this->name = new char[strlen(name) + 1]; 35 | strcpy(this->name, name); 36 | } 37 | void Person::setAge(unsigned int age) 38 | { 39 | this->age = age; 40 | } 41 | 42 | const char* Person::getName() const 43 | { 44 | return name; 45 | } 46 | unsigned int Person::getAge() const 47 | { 48 | return age; 49 | } 50 | 51 | void Person::print() const 52 | { 53 | std::cout << "Name: " << name << ", Age: " << age << std::endl; 54 | } 55 | 56 | void Person::copyFrom(const Person& other) 57 | { 58 | name = new char[strlen(other.name) + 1]; 59 | strcpy(name, other.name); 60 | age = other.age; 61 | } 62 | void Person::free() 63 | { 64 | delete[] name; 65 | name = nullptr; 66 | } 67 | -------------------------------------------------------------------------------- /Sem_10/InheritanceExample/Person/Person.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma warning (disable : 4996) 3 | #include 4 | 5 | class Person 6 | { 7 | private: 8 | char* name = nullptr; 9 | unsigned int age; 10 | 11 | void copyFrom(const Person& other); 12 | void free(); 13 | 14 | public: 15 | Person(const char* name, unsigned int age); 16 | 17 | Person() = default; 18 | Person(const Person& other); 19 | Person& operator=(const Person& other); 20 | ~Person(); 21 | 22 | void setName(const char* name); 23 | void setAge(unsigned int age); 24 | 25 | const char* getName() const; 26 | unsigned int getAge() const; 27 | 28 | void print() const; 29 | }; 30 | -------------------------------------------------------------------------------- /Sem_10/InheritanceExample/Student/Student.cpp: -------------------------------------------------------------------------------- 1 | #include "Student.h" 2 | 3 | Student::Student(const char* name, unsigned int age, unsigned int fn) : Person(name, age) 4 | { 5 | setFn(fn); 6 | } 7 | 8 | void Student::setFn(unsigned int fn) 9 | { 10 | this->fn = fn; 11 | } 12 | unsigned int Student::getFn() const 13 | { 14 | return fn; 15 | } 16 | -------------------------------------------------------------------------------- /Sem_10/InheritanceExample/Student/Student.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Person.h" 3 | 4 | class Student : public Person 5 | { 6 | private: 7 | unsigned int fn; 8 | 9 | public: 10 | Student(const char* name, unsigned int age, unsigned int fn); 11 | 12 | void setFn(unsigned int fn); 13 | unsigned int getFn() const; 14 | }; 15 | -------------------------------------------------------------------------------- /Sem_10/InheritanceExample/Teacher/Teacher.cpp: -------------------------------------------------------------------------------- 1 | #include "Teacher.h" 2 | 3 | Teacher::Teacher(const char* name, unsigned int age, const char* const* subjects, unsigned int subjectsCount) : Person(name, age) 4 | { 5 | this->subjectsCount = subjectsCount; 6 | this->subjects = new char* [subjectsCount]; 7 | 8 | for (size_t i = 0; i < subjectsCount; i++) 9 | { 10 | this->subjects[i] = new char[strlen(subjects[i]) + 1]; 11 | strcpy(this->subjects[i], subjects[i]); 12 | } 13 | } 14 | 15 | Teacher::Teacher(const Teacher& other) : Person(other) 16 | { 17 | copyFrom(other); 18 | } 19 | Teacher& Teacher::operator=(const Teacher& other) 20 | { 21 | if (this != &other) 22 | { 23 | Person::operator=(other); 24 | 25 | free(); 26 | copyFrom(other); 27 | } 28 | 29 | return *this; 30 | } 31 | Teacher::~Teacher() 32 | { 33 | free(); 34 | } 35 | 36 | void Teacher::free() 37 | { 38 | for (size_t i = 0; i < subjectsCount; i++) 39 | { 40 | delete[] subjects[i]; 41 | } 42 | delete[] subjects; 43 | subjects = nullptr; 44 | } 45 | void Teacher::copyFrom(const Teacher& other) 46 | { 47 | subjectsCount = other.subjectsCount; 48 | subjects = new char* [subjectsCount]; 49 | 50 | for (size_t i = 0; i < subjectsCount; i++) 51 | { 52 | subjects[i] = new char[strlen(other.subjects[i]) + 1]; 53 | strcpy(subjects[i], other.subjects[i]); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Sem_10/InheritanceExample/Teacher/Teacher.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma warning (disable : 4996) 3 | #include "Person.h" 4 | 5 | class Teacher : public Person 6 | { 7 | private: 8 | char** subjects; 9 | unsigned int subjectsCount; 10 | 11 | void free(); 12 | void copyFrom(const Teacher& other); 13 | 14 | public: 15 | Teacher(const char* name, unsigned int age, const char* const* subjects, unsigned int subjectsCount); 16 | Teacher(const Teacher& other); 17 | Teacher& operator=(const Teacher& other); 18 | ~Teacher(); 19 | }; 20 | -------------------------------------------------------------------------------- /Sem_10/Sets/SetOfNumbers/SetOfNumbers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class SetOfNumbers 5 | { 6 | private: 7 | unsigned char* data; 8 | unsigned maxNumber; 9 | 10 | void copyFrom(const SetOfNumbers& other); 11 | void moveFrom(SetOfNumbers&& other); 12 | 13 | void free(); 14 | 15 | public: 16 | SetOfNumbers() = default; 17 | SetOfNumbers(unsigned n); 18 | 19 | SetOfNumbers(const SetOfNumbers& other); 20 | SetOfNumbers(SetOfNumbers&& other) noexcept; 21 | 22 | SetOfNumbers& operator=(const SetOfNumbers& other); 23 | SetOfNumbers& operator=(SetOfNumbers&& other) noexcept; 24 | 25 | ~SetOfNumbers(); 26 | 27 | private: 28 | unsigned getBucketsCount() const; 29 | unsigned getBucketIndex(unsigned number) const; 30 | 31 | unsigned char getMask(unsigned number) const; 32 | 33 | public: 34 | bool add(unsigned number); 35 | bool remove(unsigned number); 36 | bool contains(unsigned number) const; 37 | 38 | unsigned getMaxNumber() const; 39 | 40 | void removeAll(); 41 | 42 | friend std::ostream& operator<<(std::ostream& os, const SetOfNumbers& set); 43 | 44 | friend SetOfNumbers setUnion(const SetOfNumbers& lhs, const SetOfNumbers& rhs); 45 | friend SetOfNumbers setIntersection(const SetOfNumbers& lhs, const SetOfNumbers& rhs); 46 | }; -------------------------------------------------------------------------------- /Sem_10/Sets/SetOfNumbers/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "SetOfNumbers.h" 2 | 3 | int main() 4 | { 5 | SetOfNumbers set1(8); 6 | for (size_t i = 0; i <= 8; i++) 7 | { 8 | set1.add(i); 9 | } 10 | std::cout << "Elements of set1: " << set1 << std::endl; 11 | 12 | set1.remove(0); 13 | set1.remove(8); 14 | set1.remove(4); 15 | std::cout << "Elements of set1 after removing 0,4,8: " << set1 << std::endl; 16 | 17 | SetOfNumbers set2(8); 18 | set2.add(8); 19 | set2.add(0); 20 | std::cout << "Elements of set2: " << set2 << std::endl; 21 | 22 | std::cout << "Union of set1 and set2 is " << setUnion(set1, set2) << std::endl; 23 | } -------------------------------------------------------------------------------- /Sem_10/Sets/SetOfNumbersByCriteria/SetOfNumbersByCriteria.cpp: -------------------------------------------------------------------------------- 1 | #include "SetOfNumbersByCriteria.h" 2 | 3 | SetOfNumbersByCriteria::SetOfNumbersByCriteria(unsigned n, std::function incl, std::function excl) : SetOfNumbers(n) 4 | { 5 | this->incl = incl; 6 | this->excl = excl; 7 | 8 | for (size_t i = 0; i <= n; i++) 9 | { 10 | if (incl(i) && !excl(i)) 11 | { 12 | add(i); 13 | } 14 | } 15 | } 16 | 17 | bool SetOfNumbersByCriteria::contains(unsigned number) const 18 | { 19 | return contains(number); 20 | } 21 | 22 | void SetOfNumbersByCriteria::setInclude(std::function incl) 23 | { 24 | this->incl = incl; 25 | removeAll(); 26 | fill(); 27 | } 28 | void SetOfNumbersByCriteria::setExclude(std::function excl) 29 | { 30 | this->excl = excl; 31 | removeAll(); 32 | fill(); 33 | } 34 | 35 | std::ostream& operator<<(std::ostream& os, const SetOfNumbersByCriteria& set) 36 | { 37 | os << static_cast(set); 38 | return os; 39 | } 40 | 41 | void SetOfNumbersByCriteria::fill() 42 | { 43 | for (size_t i = 0; i < SetOfNumbers::getMaxNumber(); i++) 44 | { 45 | if (incl(i) && !excl(i)) 46 | { 47 | add(i); 48 | } 49 | else 50 | { 51 | remove(i); 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /Sem_10/Sets/SetOfNumbersByCriteria/SetOfNumbersByCriteria.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../SetOfNumbers/SetOfNumbers.h" 3 | #include 4 | #include 5 | 6 | class SetOfNumbersByCriteria : private SetOfNumbers 7 | { 8 | private: 9 | std::function incl; 10 | std::function excl; 11 | 12 | void fill(); 13 | 14 | public: 15 | SetOfNumbersByCriteria(unsigned n, std::function incl, std::function excl); 16 | 17 | bool contains(unsigned number) const; 18 | 19 | void setInclude(std::function incl); 20 | void setExclude(std::function excl); 21 | 22 | friend std::ostream& operator<<(std::ostream& os, const SetOfNumbersByCriteria& set); 23 | }; -------------------------------------------------------------------------------- /Sem_10/Sets/SetOfNumbersByCriteria/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "SetOfNumbersByCriteria.h" 2 | 3 | bool isPrime(unsigned n); 4 | 5 | int main() 6 | { 7 | SetOfNumbersByCriteria s(10, isPrime, [](unsigned n) { return n % 2; }); 8 | std::cout << s << std::endl; 9 | 10 | s.setExclude([](unsigned n) { return n % 2 == 0; }); 11 | std::cout << s << std::endl; 12 | } 13 | 14 | bool isPrime(unsigned n) 15 | { 16 | if (n <= 1) 17 | { 18 | return false; 19 | } 20 | 21 | double sqrtOfN = sqrt(n); 22 | for (size_t divisorCandidate = 2; divisorCandidate <= sqrtOfN; divisorCandidate++) 23 | { 24 | if (n % divisorCandidate == 0) 25 | { 26 | return false; 27 | } 28 | } 29 | return true; 30 | } -------------------------------------------------------------------------------- /Sem_10/images/PersonStudent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_10/images/PersonStudent.png -------------------------------------------------------------------------------- /Sem_10/images/Student.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_10/images/Student.png -------------------------------------------------------------------------------- /Sem_11/Figures/Circle/Circle.cpp: -------------------------------------------------------------------------------- 1 | #include "Circle.h" 2 | 3 | namespace { 4 | const double pi = 3.1415; 5 | } 6 | 7 | Circle::Circle(int x, int y, double radius) : Shape(1) 8 | { 9 | this->radius = radius; 10 | setPoint(0, x, y); 11 | } 12 | 13 | double Circle::getArea() const 14 | { 15 | return pi * radius * radius; 16 | } 17 | 18 | double Circle::getPerimeter() const 19 | { 20 | return 2 * pi * radius; 21 | } 22 | 23 | bool Circle::isPointInFigure(int x, int y) const 24 | { 25 | Shape::Point p(x, y); 26 | return p.getDist(getPointAtIndex(0)) <= radius; 27 | } 28 | -------------------------------------------------------------------------------- /Sem_11/Figures/Circle/Circle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Shape/Shape.h" 3 | 4 | class Circle : public Shape 5 | { 6 | public: 7 | Circle(int x, int y, double radius); 8 | 9 | virtual double getArea() const override; 10 | virtual double getPerimeter() const override; 11 | virtual bool isPointInFigure(int x, int y) const override; 12 | 13 | private: 14 | double radius; 15 | }; 16 | -------------------------------------------------------------------------------- /Sem_11/Figures/Rectangle/Rectangle.cpp: -------------------------------------------------------------------------------- 1 | #include "Rectangle.h" 2 | 3 | Rectangle::Rectangle(int x1, int y1, int x3, int y3) : Shape(4) 4 | { 5 | setPoint(0, x1, y1); 6 | setPoint(1, x3, y1); 7 | setPoint(2, x3, y3); 8 | setPoint(3, x1, y3); 9 | } 10 | 11 | double Rectangle::getArea() const 12 | { 13 | const Point& p1 = getPointAtIndex(0); 14 | const Point& p2 = getPointAtIndex(1); 15 | const Point& p3 = getPointAtIndex(2); 16 | 17 | return p1.getDist(p2) * p2.getDist(p3); 18 | } 19 | 20 | bool Rectangle::isPointInFigure(int x, int y) const 21 | { 22 | Shape::Point p(x, y); 23 | return p.x >= getPointAtIndex(0).x && p.x <= getPointAtIndex(1).x && 24 | p.y >= getPointAtIndex(0).y && p.y <= getPointAtIndex(2).y; 25 | } 26 | -------------------------------------------------------------------------------- /Sem_11/Figures/Rectangle/Rectangle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Shape/Shape.h" 3 | 4 | class Rectangle : public Shape 5 | { 6 | public: 7 | Rectangle(int x1, int y1, int x3, int y3); 8 | 9 | virtual double getArea() const override; 10 | virtual bool isPointInFigure(int x, int y) const override; 11 | }; 12 | -------------------------------------------------------------------------------- /Sem_11/Figures/Shape/Shape.cpp: -------------------------------------------------------------------------------- 1 | #include "Shape.h" 2 | #include 3 | 4 | double Shape::getPerimeter() const 5 | { 6 | assert(pointsCount >= 3); 7 | 8 | double perimeter = 0; 9 | for (size_t i = 0; i < pointsCount - 1; i++) 10 | { 11 | perimeter += points[i].getDist(points[i + 1]); 12 | } 13 | perimeter += points[pointsCount - 1].getDist(points[0]); 14 | return perimeter; 15 | } 16 | 17 | void Shape::setPoint(unsigned index, int x, int y) 18 | { 19 | if (index >= pointsCount) 20 | { 21 | throw std::out_of_range("Invalid index!"); 22 | } 23 | points[index] = Point(x, y); 24 | } 25 | 26 | const Shape::Point& Shape::getPointAtIndex(unsigned index) const 27 | { 28 | if (index >= pointsCount) 29 | { 30 | throw std::out_of_range("Invalid index!"); 31 | } 32 | return points[index]; 33 | } 34 | 35 | Shape::Shape(size_t pointsCount) 36 | { 37 | this->pointsCount = pointsCount; 38 | points = new Point[pointsCount]; 39 | } 40 | 41 | Shape::Shape(const Shape& other) 42 | { 43 | copyFrom(other); 44 | } 45 | Shape& Shape::operator=(const Shape& other) 46 | { 47 | if (this != &other) 48 | { 49 | free(); 50 | copyFrom(other); 51 | } 52 | 53 | return *this; 54 | } 55 | Shape::~Shape() 56 | { 57 | free(); 58 | } 59 | 60 | void Shape::copyFrom(const Shape& other) 61 | { 62 | pointsCount = other.pointsCount; 63 | points = new Point[pointsCount]; 64 | for (size_t i = 0; i < pointsCount; i++) 65 | { 66 | points[i] = other.points[i]; 67 | } 68 | } 69 | void Shape::free() 70 | { 71 | delete[] points; 72 | points = nullptr; 73 | } 74 | -------------------------------------------------------------------------------- /Sem_11/Figures/Shape/Shape.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class Shape 6 | { 7 | public: 8 | Shape(size_t pointsCount); 9 | 10 | Shape(const Shape& other); 11 | Shape& operator=(const Shape& other); 12 | virtual ~Shape(); // !! 13 | 14 | void setPoint(unsigned index, int x, int y); 15 | 16 | virtual double getArea() const = 0; // pure virtual 17 | virtual double getPerimeter() const; // non-pure virtual 18 | virtual bool isPointInFigure(int x, int y) const = 0; // pure virtual 19 | 20 | protected: 21 | struct Point 22 | { 23 | int x; 24 | int y; 25 | 26 | Point() : Point(0, 0) 27 | {} 28 | Point(int x, int y) : x(x), y(y) 29 | {} 30 | 31 | double getDist(const Point& other) const 32 | { 33 | int distX = x - other.x; 34 | int distY = y - other.y; 35 | 36 | return sqrt(distX * distX + distY * distY); 37 | } 38 | }; 39 | 40 | const Point& getPointAtIndex(unsigned index) const; 41 | 42 | private: 43 | Point* points; 44 | size_t pointsCount; 45 | 46 | void copyFrom(const Shape& other); 47 | void free(); 48 | }; 49 | -------------------------------------------------------------------------------- /Sem_11/Figures/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "Circle/Circle.h" 2 | #include "Triangle/Triangle.h" 3 | #include "Rectangle/Rectangle.h" 4 | 5 | void printAreas(const Shape* const* shapes, size_t shapesCount) 6 | { 7 | for (size_t i = 0; i < shapesCount; i++) 8 | { 9 | std::cout << shapes[i]->getArea() << std::endl; 10 | } 11 | } 12 | 13 | void printPerimeters(const Shape* const* shapes, size_t shapesCount) 14 | { 15 | for (size_t i = 0; i < shapesCount; i++) 16 | { 17 | std::cout << shapes[i]->getPerimeter() << std::endl; 18 | } 19 | } 20 | 21 | void printIfPointsAreInFigures(const Shape* const* shapes, size_t shapesCount) 22 | { 23 | for (size_t i = 0; i < shapesCount; i++) 24 | { 25 | std::cout << shapes[i]->isPointInFigure(i + 1, i + 3) << std::endl; 26 | } 27 | } 28 | 29 | void freeCollection(Shape** shapes, size_t shapesCount) 30 | { 31 | for (int i = 0; i < shapesCount; i++) 32 | { 33 | delete shapes[i]; 34 | } 35 | delete[] shapes; 36 | } 37 | 38 | int main() 39 | { 40 | Shape** arr = new Shape * [4]; 41 | 42 | arr[0] = new Circle(3, 3, 4); 43 | arr[1] = new Circle(1, 4, 5); 44 | arr[2] = new Triangle(-2, -3, 1, -3, 1, 0); 45 | arr[3] = new Rectangle(3, 4, 6, 8); 46 | 47 | std::cout << "Areas:" << std::endl; 48 | printAreas(arr, 4); 49 | 50 | std::cout << std::endl << "Perimeters:" << std::endl; 51 | printPerimeters(arr, 4); 52 | 53 | std::cout << std::endl << "Points in figures:" << std::endl; 54 | printIfPointsAreInFigures(arr, 4); 55 | 56 | freeCollection(arr, 4); 57 | } 58 | -------------------------------------------------------------------------------- /Sem_11/Figures/Triangle/Triangle.cpp: -------------------------------------------------------------------------------- 1 | #include "Triangle.h" 2 | 3 | Triangle::Triangle(int x1, int y1, int x2, int y2, int x3, int y3) : Shape(3) 4 | { 5 | setPoint(0, x1, y1); 6 | setPoint(1, x2, y2); 7 | setPoint(2, x3, y3); 8 | } 9 | 10 | double Triangle::getArea() const 11 | { 12 | const Point& p1 = getPointAtIndex(0); 13 | const Point& p2 = getPointAtIndex(1); 14 | const Point& p3 = getPointAtIndex(2); 15 | 16 | double semiPer = getPerimeter() / 2; 17 | return sqrt(semiPer * (semiPer - p1.getDist(p2)) * (semiPer - p2.getDist(p3)) * (semiPer - p3.getDist(p1))); 18 | } 19 | 20 | bool Triangle::isPointInFigure(int x, int y) const 21 | { 22 | Shape::Point p(x, y); 23 | Triangle t1(getPointAtIndex(0).x, getPointAtIndex(0).y, getPointAtIndex(1).x, getPointAtIndex(1).y, p.x, p.y); 24 | Triangle t2(getPointAtIndex(2).x, getPointAtIndex(2).y, getPointAtIndex(1).x, getPointAtIndex(1).y, p.x, p.y); 25 | Triangle t3(getPointAtIndex(2).x, getPointAtIndex(2).y, getPointAtIndex(0).x, getPointAtIndex(0).y, p.x, p.y); 26 | return abs(t1.getArea() + t2.getArea() + t3.getArea() - getArea()) <= std::numeric_limits::epsilon(); 27 | } 28 | -------------------------------------------------------------------------------- /Sem_11/Figures/Triangle/Triangle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Shape/Shape.h" 3 | 4 | class Triangle : public Shape 5 | { 6 | public: 7 | Triangle(int x1, int y1, int x2, int y2, int x3, int y3); 8 | 9 | virtual double getArea() const override; 10 | virtual bool isPointInFigure(int x, int y) const override; 11 | }; 12 | -------------------------------------------------------------------------------- /Sem_11/Figures_mutualCatching/Circle/Circle.cpp: -------------------------------------------------------------------------------- 1 | #include "Circle.h" 2 | 3 | namespace { 4 | const double pi = 3.1415; 5 | } 6 | 7 | Circle::Circle(int x, int y, double radius) : Shape(1) 8 | { 9 | this->radius = radius; 10 | setPoint(0, x, y); 11 | } 12 | 13 | double Circle::getArea() const 14 | { 15 | return pi * radius * radius; 16 | } 17 | 18 | double Circle::getPerimeter() const 19 | { 20 | return 2 * pi * radius; 21 | } 22 | 23 | bool Circle::isPointInFigure(int x, int y) const 24 | { 25 | Shape::Point p(x, y); 26 | return p.getDist(getPointAtIndex(0)) <= radius; 27 | } 28 | 29 | bool Circle::intersectsWith(const Shape* other) const 30 | { 31 | return other->intersectsWithCircle(this); 32 | } 33 | 34 | bool Circle::intersectsWithCircle(const Circle* other) const 35 | { 36 | std::cout << "Formula for circle with circle" << std::endl; 37 | return true; 38 | } 39 | 40 | bool Circle::intersectsWithTriangle(const Triangle* other) const 41 | { 42 | std::cout << "Formula for circle with triangle" << std::endl; 43 | return true; 44 | } 45 | 46 | bool Circle::intersectsWithRectangle(const Rectangle* other) const 47 | { 48 | std::cout << "Formula for circle with rectangle" << std::endl; 49 | return true; 50 | } 51 | -------------------------------------------------------------------------------- /Sem_11/Figures_mutualCatching/Circle/Circle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Shape/Shape.h" 3 | 4 | class Circle : public Shape 5 | { 6 | public: 7 | Circle(int x, int y, double radius); 8 | 9 | virtual double getArea() const override; 10 | virtual double getPerimeter() const override; 11 | virtual bool isPointInFigure(int x, int y) const override; 12 | 13 | virtual bool intersectsWith(const Shape* other) const override; 14 | virtual bool intersectsWithCircle(const Circle* other) const override; 15 | virtual bool intersectsWithTriangle(const Triangle* other) const override; 16 | virtual bool intersectsWithRectangle(const Rectangle* other) const override; 17 | 18 | private: 19 | double radius; 20 | }; 21 | -------------------------------------------------------------------------------- /Sem_11/Figures_mutualCatching/Rectangle/Rectangle.cpp: -------------------------------------------------------------------------------- 1 | #include "Rectangle.h" 2 | 3 | Rectangle::Rectangle(int x1, int y1, int x3, int y3) : Shape(4) 4 | { 5 | setPoint(0, x1, y1); 6 | setPoint(1, x3, y1); 7 | setPoint(2, x3, y3); 8 | setPoint(3, x1, y3); 9 | } 10 | 11 | double Rectangle::getArea() const 12 | { 13 | const Point& p1 = getPointAtIndex(0); 14 | const Point& p2 = getPointAtIndex(1); 15 | const Point& p3 = getPointAtIndex(2); 16 | 17 | return p1.getDist(p2) * p2.getDist(p3); 18 | } 19 | 20 | bool Rectangle::isPointInFigure(int x, int y) const 21 | { 22 | Shape::Point p(x, y); 23 | return p.x >= getPointAtIndex(0).x && p.x <= getPointAtIndex(1).x && 24 | p.y >= getPointAtIndex(0).y && p.y <= getPointAtIndex(2).y; 25 | } 26 | 27 | bool Rectangle::intersectsWith(const Shape* other) const 28 | { 29 | return other->intersectsWithRectangle(this); 30 | } 31 | 32 | bool Rectangle::intersectsWithCircle(const Circle* other) const 33 | { 34 | std::cout << "Formula for rectangle with circle" << std::endl; 35 | return true; 36 | } 37 | 38 | bool Rectangle::intersectsWithTriangle(const Triangle* other) const 39 | { 40 | std::cout << "Formula for rectangle with triangle" << std::endl; 41 | return true; 42 | } 43 | 44 | bool Rectangle::intersectsWithRectangle(const Rectangle* other) const 45 | { 46 | std::cout << "Formula for rectangle with rectangle" << std::endl; 47 | return true; 48 | } 49 | -------------------------------------------------------------------------------- /Sem_11/Figures_mutualCatching/Rectangle/Rectangle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Shape/Shape.h" 3 | 4 | class Rectangle : public Shape 5 | { 6 | public: 7 | Rectangle(int x1, int y1, int x3, int y3); 8 | 9 | virtual double getArea() const override; 10 | virtual bool isPointInFigure(int x, int y) const override; 11 | 12 | virtual bool intersectsWith(const Shape* other) const override; 13 | virtual bool intersectsWithCircle(const Circle* other) const override; 14 | virtual bool intersectsWithTriangle(const Triangle* other) const override; 15 | virtual bool intersectsWithRectangle(const Rectangle* other) const override; 16 | }; 17 | -------------------------------------------------------------------------------- /Sem_11/Figures_mutualCatching/Shape/Shape.cpp: -------------------------------------------------------------------------------- 1 | #include "Shape.h" 2 | #include 3 | 4 | double Shape::getPerimeter() const 5 | { 6 | assert(pointsCount >= 3); 7 | 8 | double perimeter = 0; 9 | for (size_t i = 0; i < pointsCount - 1; i++) 10 | { 11 | perimeter += points[i].getDist(points[i + 1]); 12 | } 13 | perimeter += points[pointsCount - 1].getDist(points[0]); 14 | return perimeter; 15 | } 16 | 17 | void Shape::setPoint(unsigned index, int x, int y) 18 | { 19 | if (index >= pointsCount) 20 | { 21 | throw std::out_of_range("Invalid index!"); 22 | } 23 | points[index] = Point(x, y); 24 | } 25 | 26 | const Shape::Point& Shape::getPointAtIndex(unsigned index) const 27 | { 28 | if (index >= pointsCount) 29 | { 30 | throw std::out_of_range("Invalid index!"); 31 | } 32 | return points[index]; 33 | } 34 | 35 | Shape::Shape(size_t pointsCount) 36 | { 37 | this->pointsCount = pointsCount; 38 | points = new Point[pointsCount]; 39 | } 40 | 41 | Shape::Shape(const Shape& other) 42 | { 43 | copyFrom(other); 44 | } 45 | Shape& Shape::operator=(const Shape& other) 46 | { 47 | if (this != &other) 48 | { 49 | free(); 50 | copyFrom(other); 51 | } 52 | 53 | return *this; 54 | } 55 | Shape::~Shape() 56 | { 57 | free(); 58 | } 59 | 60 | void Shape::copyFrom(const Shape& other) 61 | { 62 | pointsCount = other.pointsCount; 63 | points = new Point[pointsCount]; 64 | for (size_t i = 0; i < pointsCount; i++) 65 | { 66 | points[i] = other.points[i]; 67 | } 68 | } 69 | void Shape::free() 70 | { 71 | delete[] points; 72 | points = nullptr; 73 | } 74 | -------------------------------------------------------------------------------- /Sem_11/Figures_mutualCatching/Shape/Shape.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class Circle; 6 | class Triangle; 7 | class Rectangle; 8 | 9 | class Shape 10 | { 11 | public: 12 | Shape(size_t pointsCount); 13 | 14 | Shape(const Shape& other); 15 | Shape& operator=(const Shape& other); 16 | virtual ~Shape(); // !! 17 | 18 | void setPoint(unsigned index, int x, int y); 19 | 20 | virtual double getArea() const = 0; // pure virtual 21 | virtual double getPerimeter() const; // non-pure virtual 22 | virtual bool isPointInFigure(int x, int y) const = 0; // pure virtual 23 | 24 | virtual bool intersectsWith(const Shape* other) const = 0; 25 | virtual bool intersectsWithCircle(const Circle* other) const = 0; 26 | virtual bool intersectsWithTriangle(const Triangle* other) const = 0; 27 | virtual bool intersectsWithRectangle(const Rectangle* other) const = 0; 28 | 29 | protected: 30 | struct Point 31 | { 32 | int x; 33 | int y; 34 | 35 | Point() : Point(0, 0) 36 | {} 37 | Point(int x, int y) : x(x), y(y) 38 | {} 39 | 40 | double getDist(const Point& other) const 41 | { 42 | int distX = x - other.x; 43 | int distY = y - other.y; 44 | 45 | return sqrt(distX * distX + distY * distY); 46 | } 47 | }; 48 | 49 | const Point& getPointAtIndex(unsigned index) const; 50 | 51 | private: 52 | Point* points; 53 | size_t pointsCount; 54 | 55 | void copyFrom(const Shape& other); 56 | void free(); 57 | }; 58 | -------------------------------------------------------------------------------- /Sem_11/Figures_mutualCatching/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "Circle/Circle.h" 2 | #include "Triangle/Triangle.h" 3 | #include "Rectangle/Rectangle.h" 4 | 5 | void printIfPointsIntersect(const Shape* const* shapes, size_t shapesCount) 6 | { 7 | for (size_t i = 0; i < shapesCount - 1; i++) 8 | { 9 | shapes[i]->intersectsWith(shapes[i + 1]); 10 | } 11 | } 12 | 13 | void freeCollection(Shape** shapes, size_t shapesCount) 14 | { 15 | for (int i = 0; i < shapesCount; i++) 16 | { 17 | delete shapes[i]; 18 | } 19 | delete[] shapes; 20 | } 21 | 22 | int main() 23 | { 24 | Shape** arr = new Shape * [4]; 25 | 26 | arr[0] = new Circle(3, 3, 4); 27 | arr[1] = new Circle(1, 4, 5); 28 | arr[2] = new Triangle(-2, -3, 1, -3, 1, 0); 29 | arr[3] = new Rectangle(3, 4, 6, 8); 30 | 31 | std::cout << "Intersection of points:" << std::endl; 32 | printIfPointsIntersect(arr, 4); 33 | 34 | freeCollection(arr, 4); 35 | } 36 | -------------------------------------------------------------------------------- /Sem_11/Figures_mutualCatching/Triangle/Triangle.cpp: -------------------------------------------------------------------------------- 1 | #include "Triangle.h" 2 | 3 | Triangle::Triangle(int x1, int y1, int x2, int y2, int x3, int y3) : Shape(3) 4 | { 5 | setPoint(0, x1, y1); 6 | setPoint(1, x2, y2); 7 | setPoint(2, x3, y3); 8 | } 9 | 10 | double Triangle::getArea() const 11 | { 12 | const Point& p1 = getPointAtIndex(0); 13 | const Point& p2 = getPointAtIndex(1); 14 | const Point& p3 = getPointAtIndex(2); 15 | 16 | double semiPer = getPerimeter() / 2; 17 | return sqrt(semiPer * (semiPer - p1.getDist(p2)) * (semiPer - p2.getDist(p3)) * (semiPer - p3.getDist(p1))); 18 | } 19 | 20 | bool Triangle::isPointInFigure(int x, int y) const 21 | { 22 | Shape::Point p(x, y); 23 | Triangle t1(getPointAtIndex(0).x, getPointAtIndex(0).y, getPointAtIndex(1).x, getPointAtIndex(1).y, p.x, p.y); 24 | Triangle t2(getPointAtIndex(2).x, getPointAtIndex(2).y, getPointAtIndex(1).x, getPointAtIndex(1).y, p.x, p.y); 25 | Triangle t3(getPointAtIndex(2).x, getPointAtIndex(2).y, getPointAtIndex(0).x, getPointAtIndex(0).y, p.x, p.y); 26 | return abs(t1.getArea() + t2.getArea() + t3.getArea() - getArea()) <= std::numeric_limits::epsilon(); 27 | } 28 | 29 | bool Triangle::intersectsWith(const Shape* other) const 30 | { 31 | return other->intersectsWithTriangle(this); 32 | } 33 | 34 | bool Triangle::intersectsWithCircle(const Circle* other) const 35 | { 36 | std::cout << "Formula for triangle with circle" << std::endl; 37 | return true; 38 | } 39 | 40 | bool Triangle::intersectsWithTriangle(const Triangle* other) const 41 | { 42 | std::cout << "Formula for triangle with triangle" << std::endl; 43 | return true; 44 | } 45 | 46 | bool Triangle::intersectsWithRectangle(const Rectangle* other) const 47 | { 48 | std::cout << "Formula for triangle with rectangle" << std::endl; 49 | return true; 50 | } 51 | -------------------------------------------------------------------------------- /Sem_11/Figures_mutualCatching/Triangle/Triangle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Shape/Shape.h" 3 | 4 | class Triangle : public Shape 5 | { 6 | public: 7 | Triangle(int x1, int y1, int x2, int y2, int x3, int y3); 8 | 9 | virtual double getArea() const override; 10 | virtual bool isPointInFigure(int x, int y) const override; 11 | 12 | virtual bool intersectsWith(const Shape* other) const override; 13 | virtual bool intersectsWithCircle(const Circle* other) const override; 14 | virtual bool intersectsWithTriangle(const Triangle* other) const override; 15 | virtual bool intersectsWithRectangle(const Rectangle* other) const override; 16 | }; 17 | -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/ArrFileReader.cpp: -------------------------------------------------------------------------------- 1 | #include "ArrFileReader.h" 2 | #include 3 | #include 4 | 5 | ArrFileReader::ArrFileReader(const MyString& filePath) : FileReader(filePath) 6 | {} 7 | 8 | void ArrFileReader::read(int*& arr, size_t& size) const 9 | { 10 | std::ifstream inFile(filePath.c_str()); 11 | if (!inFile.is_open()) 12 | { 13 | throw std::runtime_error("File does not open!"); 14 | } 15 | 16 | size = getCharCount(inFile, ' ') + 1; 17 | delete[] arr; 18 | arr = new int[size]; 19 | 20 | int i = 0; 21 | inFile.ignore(); 22 | while (!inFile.eof()) 23 | { 24 | int buff; 25 | inFile >> buff; 26 | if (inFile.eof()) 27 | { 28 | break; 29 | } 30 | arr[i++] = buff; 31 | inFile.ignore(); 32 | } 33 | 34 | inFile.close(); 35 | } 36 | 37 | int ArrFileReader::getCharCount(std::ifstream& ifs, char ch) 38 | { 39 | size_t currPos = ifs.tellg(); 40 | 41 | if (!ifs.is_open()) 42 | { 43 | return -1; 44 | } 45 | 46 | int count = 0; 47 | while (true) 48 | { 49 | char current = ifs.get(); 50 | if (ifs.eof()) 51 | { 52 | break; 53 | } 54 | if (current == ch) 55 | { 56 | count++; 57 | } 58 | } 59 | 60 | ifs.clear(); 61 | ifs.seekg(currPos); 62 | return count; 63 | } -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/ArrFileReader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "FileReader.h" 3 | 4 | class ArrFileReader : public FileReader 5 | { 6 | public: 7 | ArrFileReader(const MyString& filePath); 8 | void read(int*& arr, size_t& size) const override; 9 | 10 | private: 11 | static int getCharCount(std::ifstream& ifs, char ch); 12 | }; -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/ArrFileWriter.cpp: -------------------------------------------------------------------------------- 1 | #include "ArrFileWriter.h" 2 | #include 3 | #include 4 | 5 | ArrFileWriter::ArrFileWriter(const MyString& filePath) : FileWriter(filePath) 6 | {} 7 | 8 | void ArrFileWriter::write(const int* arr, size_t size) const 9 | { 10 | std::ofstream outFile(filePath.c_str()); 11 | if (!outFile.is_open()) 12 | { 13 | throw std::runtime_error("File does not open!"); 14 | } 15 | 16 | outFile << '['; 17 | for (size_t i = 0; i < size; i++) 18 | { 19 | outFile << arr[i]; 20 | if (i != size - 1) 21 | { 22 | outFile << ' '; 23 | } 24 | } 25 | outFile << ']'; 26 | outFile.close(); 27 | } 28 | -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/ArrFileWriter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "FileWriter.h" 3 | 4 | class ArrFileWriter : public FileWriter 5 | { 6 | public: 7 | ArrFileWriter(const MyString& filePath); 8 | void write(const int* arr, size_t size) const override; 9 | }; -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/BinaryFileReader.cpp: -------------------------------------------------------------------------------- 1 | #include "BinaryFileReader.h" 2 | #include 3 | #include 4 | 5 | BinaryFileReader::BinaryFileReader(const MyString& filePath) : FileReader(filePath) 6 | {} 7 | 8 | void BinaryFileReader::read(int*& arr, size_t& size) const 9 | { 10 | std::ifstream inFile(filePath.c_str(), std::ios::binary); 11 | if (!inFile.is_open()) 12 | { 13 | throw std::runtime_error("File does not open!"); 14 | } 15 | 16 | size = getFileSize(inFile) / sizeof(int); 17 | delete[] arr; 18 | arr = new int[size]; 19 | 20 | inFile.read((char*)arr, size * sizeof(int)); 21 | inFile.close(); 22 | } 23 | 24 | size_t BinaryFileReader::getFileSize(std::ifstream& inFile) 25 | { 26 | size_t currPos = inFile.tellg(); 27 | inFile.seekg(0, std::ios::end); 28 | size_t res = inFile.tellg(); 29 | inFile.seekg(currPos); 30 | 31 | return res; 32 | } -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/BinaryFileReader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "FileReader.h" 3 | 4 | class BinaryFileReader : public FileReader 5 | { 6 | public: 7 | BinaryFileReader(const MyString& filePath); 8 | void read(int*& arr, size_t& size) const override; 9 | 10 | private: 11 | static size_t getFileSize(std::ifstream& inFile); 12 | }; -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/BinaryFileWriter.cpp: -------------------------------------------------------------------------------- 1 | #include "BinaryFileWriter.h" 2 | #include 3 | #include 4 | 5 | BinaryFileWriter::BinaryFileWriter(const MyString& filePath) : FileWriter(filePath) 6 | {} 7 | 8 | void BinaryFileWriter::write(const int* arr, size_t size) const 9 | { 10 | std::ofstream outFile(filePath.c_str(), std::ios::binary); 11 | if (!outFile.is_open()) 12 | { 13 | throw std::runtime_error("File does not open!"); 14 | } 15 | 16 | outFile.write((const char*)arr, size * sizeof(int)); 17 | outFile.close(); 18 | } -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/BinaryFileWriter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "FileWriter.h" 3 | 4 | class BinaryFileWriter : public FileWriter 5 | { 6 | public: 7 | BinaryFileWriter(const MyString& filePath); 8 | void write(const int* arr, size_t size) const override; 9 | }; -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/CSVFileReader.cpp: -------------------------------------------------------------------------------- 1 | #include "CSVFileReader.h" 2 | #include 3 | 4 | CSVFileReader::CSVFileReader(const MyString& filePath) : FileReader(filePath) 5 | {} 6 | 7 | void CSVFileReader::read(int*& arr, size_t& size) const 8 | { 9 | std::ifstream inFile(filePath.c_str()); 10 | if (!inFile.is_open()) 11 | { 12 | throw std::runtime_error("File does not open!"); 13 | } 14 | 15 | size = getCharCount(inFile, ',') + 1; 16 | delete[] arr; 17 | arr = new int[size]; 18 | 19 | int i = 0; 20 | while (!inFile.eof()) 21 | { 22 | int buff; 23 | inFile >> buff; 24 | arr[i++] = buff; 25 | inFile.ignore(); 26 | } 27 | 28 | inFile.close(); 29 | } 30 | 31 | int CSVFileReader::getCharCount(std::ifstream& ifs, char ch) 32 | { 33 | size_t currPos = ifs.tellg(); 34 | 35 | if (!ifs.is_open()) 36 | { 37 | return -1; 38 | } 39 | 40 | int count = 0; 41 | while (true) 42 | { 43 | char current = ifs.get(); 44 | if (ifs.eof()) 45 | { 46 | break; 47 | } 48 | if (current == ch) 49 | { 50 | count++; 51 | } 52 | } 53 | 54 | ifs.clear(); 55 | ifs.seekg(currPos); 56 | return count; 57 | } -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/CSVFileReader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "FileReader.h" 3 | 4 | class CSVFileReader : public FileReader 5 | { 6 | public: 7 | CSVFileReader(const MyString& filePath); 8 | void read(int*& arr, size_t& size) const override; 9 | 10 | private: 11 | static int getCharCount(std::ifstream& ifs, char ch); 12 | }; -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/CSVFileWriter.cpp: -------------------------------------------------------------------------------- 1 | #include "CSVFileWriter.h" 2 | #include 3 | #include 4 | 5 | CSVFileWriter::CSVFileWriter(const MyString& filePath) : FileWriter(filePath) 6 | {} 7 | 8 | void CSVFileWriter::write(const int* arr, size_t size) const 9 | { 10 | std::ofstream outFile(filePath.c_str()); 11 | if (!outFile.is_open()) 12 | { 13 | throw std::runtime_error("File does not open!"); 14 | } 15 | 16 | for (size_t i = 0; i < size; i++) 17 | { 18 | outFile << arr[i]; 19 | if (i != size - 1) 20 | { 21 | outFile << ','; 22 | } 23 | } 24 | 25 | outFile.close(); 26 | } -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/CSVFileWriter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "FileWriter.h" 3 | 4 | class CSVFileWriter : public FileWriter 5 | { 6 | public: 7 | CSVFileWriter(const MyString& filePath); 8 | void write(const int* arr, size_t size) const override; 9 | }; -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/FilePath.cpp: -------------------------------------------------------------------------------- 1 | #include "FilePath.h" 2 | 3 | FilePath::FilePath(const MyString& fileName) 4 | { 5 | const char* beg = fileName.c_str(); 6 | const char* end = fileName.c_str() + fileName.getSize(); 7 | const char* iter = end; 8 | 9 | while (iter != beg && *iter != '.') 10 | { 11 | iter--; 12 | } 13 | 14 | name = StringView(beg, iter); 15 | extension = StringView(iter, end); 16 | } 17 | 18 | const StringView& FilePath::getName() const 19 | { 20 | return name; 21 | } 22 | 23 | const StringView& FilePath::getExtension() const 24 | { 25 | return extension; 26 | } -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/FilePath.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "StringView.h" 3 | 4 | class FilePath 5 | { 6 | public: 7 | FilePath(const MyString& fileName); 8 | 9 | const StringView& getName() const; 10 | const StringView& getExtension() const; 11 | 12 | private: 13 | StringView name; 14 | StringView extension; 15 | }; -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/FileReader.cpp: -------------------------------------------------------------------------------- 1 | #include "FileReader.h" 2 | 3 | FileReader::FileReader(const MyString& filePath) : filePath(filePath) 4 | {} -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/FileReader.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "MyString.h" 3 | 4 | class FileReader 5 | { 6 | public: 7 | FileReader(const MyString& filePath); 8 | virtual ~FileReader() = default; 9 | 10 | virtual void read(int*& arr, size_t& size) const = 0; 11 | 12 | protected: 13 | MyString filePath; 14 | }; -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/FileWriter.cpp: -------------------------------------------------------------------------------- 1 | #include "FileWriter.h" 2 | 3 | FileWriter::FileWriter(const MyString& filePath) : filePath(filePath) 4 | {} -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/FileWriter.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "MyString.h" 3 | 4 | class FileWriter 5 | { 6 | public: 7 | FileWriter(const MyString& filePath); 8 | virtual ~FileWriter() = default; 9 | 10 | virtual void write(const int* arr, size_t size) const = 0; 11 | 12 | protected: 13 | MyString filePath; 14 | }; -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/MyString.cpp: -------------------------------------------------------------------------------- 1 | #include "MyString.h" 2 | #include 3 | #include 4 | #include 5 | 6 | #pragma warning (disable : 4996) 7 | 8 | void MyString::concat(const MyString& other) 9 | { 10 | if (!str || !other.str) 11 | { 12 | throw std::logic_error("Null strings can't be concatenated"); 13 | } 14 | 15 | char* temp = new char[size + other.size + 1]; 16 | strcpy(temp, str); 17 | strcat(temp, other.str); 18 | 19 | free(); 20 | str = temp; 21 | size += other.size; 22 | } 23 | 24 | const char* MyString::c_str() const 25 | { 26 | return str; 27 | } 28 | 29 | size_t MyString::getSize() const 30 | { 31 | return size; 32 | } 33 | 34 | MyString& MyString::operator+=(const MyString& other) 35 | { 36 | concat(other); 37 | return *this; 38 | } 39 | 40 | std::ostream& operator<<(std::ostream& os, const MyString& str) 41 | { 42 | return os << str.str; 43 | } 44 | std::istream& operator>>(std::istream& is, MyString& str) 45 | { 46 | char buff[1024]; 47 | is >> std::setw(1024) >> buff; 48 | size_t len = strlen(buff); 49 | 50 | delete[] str.str; 51 | str.str = new char[len + 1]; 52 | strcpy(str.str, buff); 53 | 54 | return is; 55 | } 56 | 57 | MyString operator+(const MyString& lhs, const MyString& rhs) 58 | { 59 | MyString lhsCopy(lhs); 60 | lhsCopy += rhs; 61 | return lhsCopy; 62 | } 63 | 64 | bool operator==(const MyString& lhs, const MyString& rhs) 65 | { 66 | if (!lhs.c_str() || !rhs.c_str()) 67 | { 68 | throw std::logic_error("Null strings can't be compared"); 69 | } 70 | return strcmp(lhs.c_str(), rhs.c_str()) == 0; 71 | } 72 | bool operator<(const MyString& lhs, const MyString& rhs) 73 | { 74 | if (!lhs.c_str() || !rhs.c_str()) 75 | { 76 | throw std::logic_error("Null strings can't be compared"); 77 | } 78 | return strcmp(lhs.c_str(), rhs.c_str()) < 0; 79 | } 80 | bool operator>(const MyString& lhs, const MyString& rhs) 81 | { 82 | if (!lhs.c_str() || !rhs.c_str()) 83 | { 84 | throw std::logic_error("Null strings can't be compared"); 85 | } 86 | return strcmp(lhs.c_str(), rhs.c_str()) > 0; 87 | } 88 | 89 | MyString::MyString(const char* str) 90 | { 91 | if (str == nullptr || this->str == str) 92 | { 93 | throw std::invalid_argument("Invalid parameter!"); 94 | } 95 | 96 | size_t len = strlen(str); 97 | this->str = new char[len + 1]; 98 | strcpy(this->str, str); 99 | size = len; 100 | } 101 | 102 | MyString::MyString(const MyString& other) 103 | { 104 | copyFrom(other); 105 | } 106 | MyString& MyString::operator=(const MyString& other) 107 | { 108 | if (this != &other) 109 | { 110 | free(); 111 | copyFrom(other); 112 | } 113 | return *this; 114 | } 115 | MyString::~MyString() 116 | { 117 | free(); 118 | } 119 | 120 | void MyString::copyFrom(const MyString& other) 121 | { 122 | str = new char[strlen(other.str) + 1]; 123 | strcpy(str, other.str); 124 | size = other.size; 125 | } 126 | void MyString::free() 127 | { 128 | delete[] str; 129 | } 130 | -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/MyString.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class MyString 5 | { 6 | private: 7 | char* str = nullptr; 8 | size_t size = 0; 9 | 10 | void copyFrom(const MyString& other); 11 | void free(); 12 | 13 | public: 14 | MyString(const char* str); 15 | 16 | MyString() = default; 17 | MyString(const MyString& other); 18 | MyString& operator=(const MyString& other); 19 | ~MyString(); 20 | 21 | void concat(const MyString& other); 22 | 23 | const char* c_str() const; 24 | 25 | size_t getSize() const; 26 | 27 | MyString& operator+=(const MyString& other); 28 | 29 | friend std::ostream& operator<<(std::ostream& os, const MyString& str); 30 | friend std::istream& operator>>(std::istream& is, MyString& str); 31 | }; 32 | 33 | MyString operator+(const MyString& lhs, const MyString& rhs); 34 | 35 | bool operator==(const MyString& lhs, const MyString& rhs); 36 | bool operator<(const MyString& lhs, const MyString& rhs); 37 | bool operator>(const MyString& lhs, const MyString& rhs); 38 | -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/Source.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "FilePath.h" 3 | #include "BinaryFileReader.h" 4 | #include "BinaryFileWriter.h" 5 | #include "CSVFileReader.h" 6 | #include "CSVFileWriter.h" 7 | #include "ArrFileReader.h" 8 | #include "ArrFileWriter.h" 9 | 10 | FileReader* getFileReader(const MyString& filePath) 11 | { 12 | FilePath path(filePath); 13 | 14 | if (path.getExtension() == ".dat") 15 | { 16 | return new BinaryFileReader(filePath); 17 | } 18 | if (path.getExtension() == ".csv") 19 | { 20 | return new CSVFileReader(filePath); 21 | } 22 | if (path.getExtension() == ".arr") 23 | { 24 | return new ArrFileReader(filePath); 25 | } 26 | 27 | throw std::invalid_argument("Invalid file extension"); 28 | } 29 | 30 | FileWriter* getFileWriter(const MyString& filePath) 31 | { 32 | FilePath path(filePath); 33 | 34 | if (path.getExtension() == ".dat") 35 | { 36 | return new BinaryFileWriter(filePath); 37 | } 38 | if (path.getExtension() == ".csv") 39 | { 40 | return new CSVFileWriter(filePath); 41 | } 42 | if (path.getExtension() == ".arr") 43 | { 44 | return new ArrFileWriter(filePath); 45 | } 46 | 47 | throw std::invalid_argument("Invalid file extension"); 48 | } 49 | 50 | void selectionSort(int* arr, size_t size) 51 | { 52 | for (size_t i = 0; i < size - 1; i++) 53 | { 54 | int minElIndex = i; 55 | for (size_t j = i + 1; j < size; j++) 56 | { 57 | if (arr[j] < arr[minElIndex]) 58 | { 59 | minElIndex = j; 60 | } 61 | } 62 | 63 | if (minElIndex != i) 64 | { 65 | std::swap(arr[minElIndex], arr[i]); 66 | } 67 | } 68 | } 69 | 70 | 71 | void transfer(const MyString& inFile, const MyString& outFile) 72 | { 73 | int* arr = nullptr; 74 | size_t size; 75 | 76 | FileReader* reader = getFileReader(inFile); 77 | reader->read(arr, size); 78 | selectionSort(arr, size); 79 | 80 | FileWriter* writer = getFileWriter(outFile); 81 | writer->write(arr, size); 82 | delete[] arr; 83 | } 84 | 85 | int main() 86 | { 87 | transfer("numbers.dat", "numbers2.arr"); 88 | } 89 | -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/StringView.cpp: -------------------------------------------------------------------------------- 1 | #include "StringView.h" 2 | #include 3 | #include 4 | 5 | StringView::StringView(const char* begin, const char* end) : begin(begin), end(end) 6 | {} 7 | 8 | StringView::StringView(const char* str) : StringView(str, str + strlen(str)) 9 | {} 10 | 11 | StringView::StringView(const MyString& str) : StringView(str.c_str()) 12 | {} 13 | 14 | size_t StringView::length() const 15 | { 16 | return end - begin; 17 | } 18 | 19 | char StringView::operator[](size_t index) const 20 | { 21 | return begin[index]; 22 | } 23 | 24 | StringView StringView::substr(size_t from, size_t length) const 25 | { 26 | if (begin + from + length > end) 27 | { 28 | throw std::length_error("Error: Substr out of range"); 29 | } 30 | return StringView(begin + from, begin + from + length); 31 | } 32 | 33 | std::ostream& operator<<(std::ostream& os, const StringView& strView) 34 | { 35 | const char* iter = strView.begin; 36 | while (iter != strView.end) 37 | { 38 | os << *iter; 39 | iter++; 40 | } 41 | return os; 42 | } 43 | 44 | bool operator==(const StringView& lhs, const StringView& rhs) 45 | { 46 | if (lhs.length() != rhs.length()) 47 | { 48 | return false; 49 | } 50 | 51 | for (size_t i = 0; i < lhs.length(); i++) 52 | { 53 | if (lhs[i] != rhs[i]) 54 | { 55 | return false; 56 | } 57 | } 58 | return true; 59 | } 60 | 61 | bool operator!=(const StringView& lhs, const StringView& rhs) 62 | { 63 | return !operator==(lhs, rhs); 64 | } 65 | -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/StringView.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include "MyString.h" 4 | 5 | class StringView 6 | { 7 | public: 8 | StringView() = default; 9 | StringView(const char* begin, const char* end); 10 | StringView(const char* str); 11 | StringView(const MyString& string); 12 | 13 | size_t length() const; 14 | 15 | char operator[](size_t ind) const; 16 | 17 | StringView substr(size_t from, size_t length) const; 18 | 19 | friend std::ostream& operator<<(std::ostream&, const StringView& strView); 20 | 21 | private: 22 | const char* begin = nullptr; 23 | const char* end = nullptr; // one pos after the last char 24 | }; 25 | 26 | bool operator==(const StringView& lhs, const StringView& rhs); 27 | bool operator!=(const StringView& lhs, const StringView& rhs); -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/numbers.arr: -------------------------------------------------------------------------------- 1 | [1 2 3 4] -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/numbers.csv: -------------------------------------------------------------------------------- 1 | 1,2,3,4 -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/numbers.dat: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /Sem_11/ReadAndWritePolymorphicallyToFiles/numbers2.arr: -------------------------------------------------------------------------------- 1 | [1 2 3 4] -------------------------------------------------------------------------------- /Sem_11/images/ConstrDestrCallingVirtualMethods.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_11/images/ConstrDestrCallingVirtualMethods.png -------------------------------------------------------------------------------- /Sem_11/images/DynamicBindingExampleOutput.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_11/images/DynamicBindingExampleOutput.png -------------------------------------------------------------------------------- /Sem_11/images/StaticBindingExampleOutput.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_11/images/StaticBindingExampleOutput.png -------------------------------------------------------------------------------- /Sem_11/images/VirtualTables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_11/images/VirtualTables.png -------------------------------------------------------------------------------- /Sem_11/images/VtableVptr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_11/images/VtableVptr.png -------------------------------------------------------------------------------- /Sem_12/AnimalCollection/AnimalCollection/Farm.cpp: -------------------------------------------------------------------------------- 1 | #include "Farm.h" 2 | #include "../Factory/Factory.h" 3 | #include 4 | 5 | bool Farm::addAnimal(Animal::AnimalType animalType) 6 | { 7 | Animal* newAnimal = AnimalFactory::createAnimal(animalType); 8 | 9 | if (newAnimal) 10 | { 11 | if (count == capacity) 12 | { 13 | resize(); 14 | } 15 | animals[count++] = newAnimal; 16 | } 17 | 18 | return newAnimal; 19 | } 20 | 21 | void Farm::allSayHello() const 22 | { 23 | for (size_t i = 0; i < count; i++) 24 | { 25 | animals[i]->sayHello(); 26 | } 27 | } 28 | 29 | Animal* Farm::operator[](unsigned index) 30 | { 31 | assert(index < count); 32 | return animals[index]; 33 | } 34 | const Animal* Farm::operator[](unsigned index) const 35 | { 36 | assert(index < count); 37 | return animals[index]; 38 | } 39 | 40 | size_t Farm::size() const 41 | { 42 | return count; 43 | } 44 | 45 | Farm::Farm() 46 | { 47 | animals = new Animal * [capacity] {nullptr}; 48 | } 49 | Farm::Farm(const Farm& other) 50 | { 51 | copyFrom(other); 52 | } 53 | Farm& Farm::operator=(const Farm& other) 54 | { 55 | if (this != &other) 56 | { 57 | free(); 58 | copyFrom(other); 59 | } 60 | return *this; 61 | } 62 | Farm::~Farm() 63 | { 64 | free(); 65 | } 66 | 67 | void Farm::copyFrom(const Farm& other) 68 | { 69 | count = other.count; 70 | capacity = other.capacity; 71 | 72 | animals = new Animal * [capacity]; 73 | for (size_t i = 0; i < count; i++) 74 | { 75 | animals[i] = other.animals[i]->clone(); 76 | } 77 | } 78 | void Farm::free() 79 | { 80 | for (size_t i = 0; i < count; i++) 81 | { 82 | delete animals[i]; 83 | } 84 | delete[] animals; 85 | } 86 | void Farm::resize() 87 | { 88 | Animal** resizedCollection = new Animal * [capacity *= 2]; 89 | 90 | for (size_t i = 0; i < count; i++) 91 | { 92 | resizedCollection[i] = animals[i]; 93 | } 94 | 95 | delete[] animals; 96 | animals = resizedCollection; 97 | } 98 | -------------------------------------------------------------------------------- /Sem_12/AnimalCollection/AnimalCollection/Farm.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Animals/Animal.h" 3 | 4 | class Farm 5 | { 6 | public: 7 | Farm(); 8 | Farm(const Farm& other); 9 | Farm& operator=(const Farm& other); 10 | ~Farm(); 11 | 12 | bool addAnimal(Animal::AnimalType animalType); 13 | 14 | void allSayHello() const; 15 | 16 | Animal* operator[](unsigned index); 17 | const Animal* operator[](unsigned index) const; 18 | 19 | size_t size() const; 20 | 21 | private: 22 | Animal** animals; 23 | 24 | size_t count = 0; 25 | size_t capacity = 8; 26 | 27 | void copyFrom(const Farm& other); 28 | void free(); 29 | void resize(); 30 | }; 31 | -------------------------------------------------------------------------------- /Sem_12/AnimalCollection/Animals/Animal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class Animal 5 | { 6 | public: 7 | virtual void sayHello() const = 0; 8 | 9 | virtual Animal* clone() const = 0; 10 | 11 | virtual ~Animal() = default; 12 | 13 | enum class AnimalType 14 | { 15 | Dog, 16 | Cat, 17 | Mouse 18 | }; 19 | }; -------------------------------------------------------------------------------- /Sem_12/AnimalCollection/Animals/Cat.cpp: -------------------------------------------------------------------------------- 1 | #include "Cat.h" 2 | 3 | void Cat::sayHello() const 4 | { 5 | std::cout << "Hello, I am a cat!" << std::endl; 6 | } 7 | 8 | Animal* Cat::clone() const 9 | { 10 | return new Cat(*this); 11 | } -------------------------------------------------------------------------------- /Sem_12/AnimalCollection/Animals/Cat.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Animal.h" 3 | 4 | class Cat : public Animal 5 | { 6 | public: 7 | virtual void sayHello() const override; 8 | virtual Animal* clone() const override; 9 | }; -------------------------------------------------------------------------------- /Sem_12/AnimalCollection/Animals/Dog.cpp: -------------------------------------------------------------------------------- 1 | #include "Dog.h" 2 | 3 | void Dog::sayHello() const 4 | { 5 | std::cout << "Hello, I am a dog!" << std::endl; 6 | } 7 | 8 | Animal* Dog::clone() const 9 | { 10 | return new Dog(*this); 11 | } -------------------------------------------------------------------------------- /Sem_12/AnimalCollection/Animals/Dog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Animal.h" 3 | 4 | class Dog : public Animal 5 | { 6 | public: 7 | virtual void sayHello() const override; 8 | virtual Animal* clone() const override; 9 | }; -------------------------------------------------------------------------------- /Sem_12/AnimalCollection/Animals/Mouse.cpp: -------------------------------------------------------------------------------- 1 | #include "Mouse.h" 2 | 3 | void Mouse::sayHello() const 4 | { 5 | std::cout << "Hello, I am a mouse!" << std::endl; 6 | } 7 | 8 | Animal* Mouse::clone() const 9 | { 10 | return new Mouse(*this); 11 | } -------------------------------------------------------------------------------- /Sem_12/AnimalCollection/Animals/Mouse.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Animal.h" 3 | 4 | class Mouse : public Animal 5 | { 6 | public: 7 | virtual void sayHello() const override; 8 | virtual Animal* clone() const override; 9 | }; -------------------------------------------------------------------------------- /Sem_12/AnimalCollection/Factory/Factory.cpp: -------------------------------------------------------------------------------- 1 | #include "Factory.h" 2 | #include "../Animals/Cat.h" 3 | #include "../Animals/Dog.h" 4 | #include "../Animals/Mouse.h" 5 | 6 | Animal* AnimalFactory::createAnimal(Animal::AnimalType animalType) 7 | { 8 | switch (animalType) 9 | { 10 | case Animal::AnimalType::Cat: return new Cat(); 11 | case Animal::AnimalType::Dog: return new Dog(); 12 | case Animal::AnimalType::Mouse: return new Mouse(); 13 | } 14 | 15 | return nullptr; 16 | } -------------------------------------------------------------------------------- /Sem_12/AnimalCollection/Factory/Factory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Animals/Animal.h" 3 | 4 | class AnimalFactory 5 | { 6 | public: 7 | static Animal* createAnimal(Animal::AnimalType animalType); 8 | }; -------------------------------------------------------------------------------- /Sem_12/AnimalCollection/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "AnimalCollection/Farm.h" 2 | 3 | int main() 4 | { 5 | Farm myFarm; 6 | 7 | while (true) 8 | { 9 | unsigned animalId; 10 | std::cin >> animalId; 11 | 12 | bool result = myFarm.addAnimal(static_cast(animalId)); 13 | 14 | if (result) 15 | { 16 | system("cls"); 17 | 18 | std::cout << "Current number of animals in the farm: " << myFarm.size() << std::endl << std::endl; 19 | 20 | std::cout << "They say hello:" << std::endl; 21 | for (size_t i = 0; i < myFarm.size(); i++) 22 | { 23 | myFarm[i]->sayHello(); 24 | } 25 | } 26 | else 27 | { 28 | std::cout << "Invalid animal type!" << std::endl; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sem_12/AnimalCollection_AbstractFactory/Animal.cpp: -------------------------------------------------------------------------------- 1 | #include "Animal.h" 2 | #include "AnimalFactory.hpp" 3 | 4 | AnimalCreator::AnimalCreator(const std::string& animalName) : animalName(animalName) 5 | { 6 | AnimalFactory::getFactory().registerAnimalCreator(this); 7 | } 8 | 9 | const std::string& AnimalCreator::getAnimalName() const 10 | { 11 | return animalName; 12 | } 13 | -------------------------------------------------------------------------------- /Sem_12/AnimalCollection_AbstractFactory/Animal.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class Animal 6 | { 7 | public: 8 | virtual void sayHello() const = 0; 9 | virtual Animal* clone() const = 0; 10 | virtual ~Animal() = default; 11 | }; 12 | 13 | class AnimalCreator 14 | { 15 | public: 16 | AnimalCreator(const std::string& animalName); 17 | virtual ~AnimalCreator() = default; 18 | const std::string& getAnimalName() const; 19 | 20 | virtual Animal* createAnimal(std::istream& is) const = 0; 21 | 22 | private: 23 | std::string animalName; 24 | }; 25 | -------------------------------------------------------------------------------- /Sem_12/AnimalCollection_AbstractFactory/AnimalCollection.cpp: -------------------------------------------------------------------------------- 1 | #include "AnimalCollection.h" 2 | #include "AnimalFactory.hpp" 3 | #include 4 | 5 | void AnimalCollection::createAnimal(std::istream& is) 6 | { 7 | Animal* newAnimal = AnimalFactory::getFactory().createAnimal(is); 8 | 9 | if (newAnimal) 10 | { 11 | if (count == capacity) 12 | { 13 | resize(); 14 | } 15 | animals[count++] = newAnimal; 16 | } 17 | } 18 | 19 | void AnimalCollection::allSayHello() const 20 | { 21 | for (size_t i = 0; i < count; i++) 22 | { 23 | animals[i]->sayHello(); 24 | } 25 | } 26 | 27 | Animal* AnimalCollection::operator[](unsigned index) 28 | { 29 | if (index >= count) 30 | { 31 | throw std::out_of_range("Index is out of range"); 32 | } 33 | return animals[index]; 34 | } 35 | const Animal* AnimalCollection::operator[](unsigned index) const 36 | { 37 | if (index >= count) 38 | { 39 | throw std::out_of_range("Index is out of range"); 40 | } 41 | return animals[index]; 42 | } 43 | 44 | size_t AnimalCollection::size() const 45 | { 46 | return count; 47 | } 48 | 49 | AnimalCollection::AnimalCollection() 50 | { 51 | animals = new Animal * [capacity] {nullptr}; 52 | } 53 | AnimalCollection::AnimalCollection(const AnimalCollection& other) 54 | { 55 | copyFrom(other); 56 | } 57 | AnimalCollection& AnimalCollection::operator=(const AnimalCollection& other) 58 | { 59 | if (this != &other) 60 | { 61 | free(); 62 | copyFrom(other); 63 | } 64 | return *this; 65 | } 66 | AnimalCollection::~AnimalCollection() 67 | { 68 | free(); 69 | } 70 | 71 | void AnimalCollection::copyFrom(const AnimalCollection& other) 72 | { 73 | count = other.count; 74 | capacity = other.capacity; 75 | 76 | animals = new Animal * [capacity]; 77 | for (size_t i = 0; i < count; i++) 78 | { 79 | animals[i] = other.animals[i]->clone(); 80 | } 81 | } 82 | void AnimalCollection::free() 83 | { 84 | for (size_t i = 0; i < count; i++) 85 | { 86 | delete animals[i]; 87 | } 88 | delete[] animals; 89 | } 90 | void AnimalCollection::resize() 91 | { 92 | Animal** resizedCollection = new Animal * [capacity *= 2]; 93 | 94 | for (size_t i = 0; i < count; i++) 95 | { 96 | resizedCollection[i] = animals[i]; 97 | } 98 | 99 | delete[] animals; 100 | animals = resizedCollection; 101 | } -------------------------------------------------------------------------------- /Sem_12/AnimalCollection_AbstractFactory/AnimalCollection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Animal.h" 3 | 4 | class AnimalCollection 5 | { 6 | public: 7 | AnimalCollection(); 8 | AnimalCollection(const AnimalCollection& other); 9 | AnimalCollection& operator=(const AnimalCollection& other); 10 | ~AnimalCollection(); 11 | 12 | void createAnimal(std::istream& is); 13 | 14 | void allSayHello() const; 15 | 16 | Animal* operator[](unsigned index); 17 | const Animal* operator[](unsigned index) const; 18 | 19 | size_t size() const; 20 | 21 | private: 22 | Animal** animals; 23 | 24 | size_t count = 0; 25 | size_t capacity = 8; 26 | 27 | void copyFrom(const AnimalCollection& other); 28 | void free(); 29 | void resize(); 30 | }; -------------------------------------------------------------------------------- /Sem_12/AnimalCollection_AbstractFactory/AnimalFactory.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Animal.h" 3 | #include 4 | #include 5 | #include 6 | 7 | class AnimalFactory 8 | { 9 | public: 10 | static AnimalFactory& getFactory() 11 | { 12 | static AnimalFactory factory; 13 | return factory; 14 | } 15 | 16 | void registerAnimalCreator(const AnimalCreator* creator) 17 | { 18 | assert(count < MAX_CREATORS_COUNT); 19 | creators[count++] = creator; 20 | } 21 | 22 | Animal* createAnimal(std::istream& is) 23 | { 24 | std::string name; 25 | is >> name; 26 | 27 | const AnimalCreator* creator = getCreator(name); 28 | if (creator) 29 | { 30 | return creator->createAnimal(is); 31 | } 32 | else 33 | { 34 | is.ignore(std::numeric_limits::max(), '\n'); 35 | return nullptr; 36 | } 37 | } 38 | 39 | private: 40 | static constexpr size_t MAX_CREATORS_COUNT = 10; 41 | const AnimalCreator* creators[MAX_CREATORS_COUNT]; 42 | size_t count; 43 | 44 | const AnimalCreator* getCreator(const std::string& str) const 45 | { 46 | for (size_t i = 0; i < count; i++) 47 | { 48 | if (creators[i]->getAnimalName() == str) 49 | { 50 | return creators[i]; 51 | } 52 | } 53 | return nullptr; 54 | } 55 | 56 | AnimalFactory() : count(0) 57 | {}; 58 | ~AnimalFactory() = default; 59 | AnimalFactory(const AnimalFactory&) = delete; 60 | AnimalFactory& operator=(const AnimalFactory&) = delete; 61 | }; 62 | -------------------------------------------------------------------------------- /Sem_12/AnimalCollection_AbstractFactory/Cat.cpp: -------------------------------------------------------------------------------- 1 | #include "Cat.h" 2 | 3 | void Cat::sayHello() const 4 | { 5 | std::cout << "Hello, I am a cat!" << std::endl; 6 | } 7 | 8 | Animal* Cat::clone() const 9 | { 10 | return new Cat(*this); 11 | } 12 | 13 | CatCreator::CatCreator() : AnimalCreator("cat") 14 | {} 15 | 16 | Animal* CatCreator::createAnimal(std::istream& is) const 17 | { 18 | return new Cat(); 19 | } 20 | 21 | static CatCreator __; 22 | -------------------------------------------------------------------------------- /Sem_12/AnimalCollection_AbstractFactory/Cat.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Animal.h" 3 | 4 | class Cat : public Animal 5 | { 6 | public: 7 | virtual void sayHello() const override; 8 | virtual Animal* clone() const override; 9 | }; 10 | 11 | class CatCreator : public AnimalCreator 12 | { 13 | public : 14 | CatCreator(); 15 | virtual Animal* createAnimal(std::istream& is) const override; 16 | }; 17 | -------------------------------------------------------------------------------- /Sem_12/AnimalCollection_AbstractFactory/Dog.cpp: -------------------------------------------------------------------------------- 1 | #include "Dog.h" 2 | #include 3 | 4 | Dog::Dog(const std::string& breed) 5 | { 6 | this->breed = breed; 7 | } 8 | 9 | void Dog::sayHello() const 10 | { 11 | std::cout << "Hello, I am a dog! My breed is " << breed << std::endl; 12 | } 13 | 14 | Animal* Dog::clone() const 15 | { 16 | return new Dog(*this); 17 | } 18 | 19 | const std::string& Dog::getBreed() const 20 | { 21 | return breed; 22 | } 23 | 24 | DogCreator::DogCreator() : AnimalCreator("dog") 25 | {} 26 | 27 | Animal* DogCreator::createAnimal(std::istream& is) const 28 | { 29 | std::string breed; 30 | is >> breed; 31 | return new Dog(breed); 32 | } 33 | 34 | static DogCreator __; 35 | -------------------------------------------------------------------------------- /Sem_12/AnimalCollection_AbstractFactory/Dog.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Animal.h" 3 | #include 4 | 5 | class Dog : public Animal 6 | { 7 | public: 8 | Dog(const std::string& breed); 9 | virtual void sayHello() const override; 10 | virtual Animal* clone() const override; 11 | 12 | const std::string& getBreed() const; 13 | 14 | private: 15 | std::string breed; 16 | }; 17 | 18 | class DogCreator : public AnimalCreator 19 | { 20 | public : 21 | DogCreator(); 22 | virtual Animal* createAnimal(std::istream& is) const override; 23 | }; 24 | -------------------------------------------------------------------------------- /Sem_12/AnimalCollection_AbstractFactory/Snake.cpp: -------------------------------------------------------------------------------- 1 | #include "Snake.h" 2 | 3 | Snake::Snake(size_t length, bool isVenomous) : length(length), isVenomous(isVenomous) 4 | {} 5 | 6 | void Snake::sayHello() const 7 | { 8 | std::cout << "Hello, I am a snake! My length is " << length << ". Am I venomous? " << isVenomous << std::endl; 9 | } 10 | 11 | Animal* Snake::clone() const 12 | { 13 | return new Snake(*this); 14 | } 15 | 16 | size_t Snake::getSnakeLength() const 17 | { 18 | return length; 19 | } 20 | bool Snake::getIsVenomous() const 21 | { 22 | return isVenomous; 23 | } 24 | 25 | SnakeCreator::SnakeCreator() : AnimalCreator("snake") 26 | {} 27 | 28 | Animal* SnakeCreator::createAnimal(std::istream& is) const 29 | { 30 | size_t length; 31 | bool isVenomous; 32 | is >> length >> isVenomous; 33 | return new Snake(length, isVenomous); 34 | } 35 | 36 | static SnakeCreator __; 37 | -------------------------------------------------------------------------------- /Sem_12/AnimalCollection_AbstractFactory/Snake.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "Animal.h" 3 | 4 | class Snake : public Animal 5 | { 6 | public: 7 | Snake(size_t length, bool isVenomous ); 8 | virtual void sayHello() const override; 9 | virtual Animal* clone() const override; 10 | 11 | size_t getSnakeLength() const; 12 | bool getIsVenomous() const; 13 | 14 | private: 15 | size_t length; 16 | bool isVenomous; 17 | }; 18 | 19 | class SnakeCreator : public AnimalCreator 20 | { 21 | public : 22 | SnakeCreator(); 23 | virtual Animal* createAnimal(std::istream& is) const override; 24 | }; 25 | -------------------------------------------------------------------------------- /Sem_12/AnimalCollection_AbstractFactory/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "AnimalCollection.h" 2 | #include 3 | 4 | int main() 5 | { 6 | std::ifstream ifs("animals.txt"); 7 | if (!ifs.is_open()) 8 | { 9 | return -1; 10 | } 11 | 12 | size_t animalsCount; 13 | ifs >> animalsCount; 14 | 15 | AnimalCollection coll; 16 | for (size_t i = 0; i < animalsCount; ++i) 17 | { 18 | coll.createAnimal(ifs); 19 | } 20 | 21 | ifs.close(); 22 | 23 | for (size_t i = 0; i < animalsCount; i++) 24 | { 25 | coll[i]->sayHello(); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sem_12/AnimalCollection_AbstractFactory/animals.txt: -------------------------------------------------------------------------------- 1 | 5 2 | dog poodle 3 | cat 4 | snake 23 1 5 | snake 1 0 6 | dog bulldog -------------------------------------------------------------------------------- /Sem_12/README.md: -------------------------------------------------------------------------------- 1 | # Колекция от обекти в полиморфна йерархия (хетерогенни контейнери) 2 | 3 | Можем да реализираме хетерогенна колекция (от различни типове **с общ базов клас**) чрез масив от указатели. Указателите трябва да са от типа на базовия клас. 4 | ```c++ 5 | struct Dog 6 | { 7 | virtual void printBreed() const = 0; 8 | virtual ~Dog() {} 9 | }; 10 | 11 | struct GoldenRetriever : Dog 12 | { 13 | virtual void printBreed() const override 14 | { 15 | std::cout << "My breed is Golden Retriever!" << std::endl; 16 | } 17 | }; 18 | struct Huskita : Dog 19 | { 20 | virtual void printBreed() const override 21 | { 22 | std::cout << "My breed is Huskita!" << std::endl; 23 | } 24 | }; 25 | struct Poodle : Dog 26 | { 27 | virtual void printBreed() const override 28 | { 29 | std::cout << "My breed is Poodle!" << std::endl; 30 | } 31 | }; 32 | 33 | class DogsCollection 34 | { 35 | private: 36 | Dog** dogs; 37 | 38 | size_t count; 39 | size_t capacity; 40 | 41 | void copyFrom(const DogsCollection& other); 42 | void free(); 43 | 44 | public: 45 | DogsCollection(); 46 | DogsCollection(const DogsCollection&); 47 | DogsCollection& operator=(const DogsCollection&); 48 | ~DogsCollection(); 49 | 50 | void addGoldenRetriever(); 51 | void addHuskita(); 52 | void addPoodle(); 53 | }; 54 | 55 | void DogsCollection::addGoldenRetriever() 56 | { 57 | dogs[count++] = new GoldenRetriever(); 58 | } 59 | void DogsCollection::addHuskita() 60 | { 61 | dogs[count++] = new Huskita(); 62 | } 63 | void DogsCollection::addPoodle() 64 | { 65 | dogs[count++] = new Poodle(); 66 | } 67 | ``` 68 | 69 | ## Триене 70 | Понеже има виртуален деструктор в базовия клас, не се интересуваме какви са обектите, които трием от колекцията. 71 | ```c++ 72 | void DogsCollection::free() 73 | { 74 | for (size_t i = 0; i < count; i++) 75 | { 76 | delete dogs[i]; 77 | } 78 | delete[] dogs; 79 | } 80 | ``` 81 | 82 | ## Копиране 83 | Искаме да реализираме копиране на колекцията. Това трябва да стане без да нарушаваме абстракцията – искаме обеките да се копират без да се налага да преглеждаме типовете им. Затова дефинираме виртуална функция clone, която връща копие на текущия обект. Разписваме clone във всеки от наследниците. 84 | ```c++ 85 | struct Dog 86 | { 87 | // ... 88 | virtual ~Dog() {} 89 | virtual Dog* clone() const = 0; 90 | }; 91 | 92 | struct GoldenRetriever : Dog 93 | { 94 | // ... 95 | virtual Dog* clone() const override 96 | { 97 | return new GoldenRetriever(*this); 98 | } 99 | }; 100 | struct Huskita : Dog 101 | { 102 | // ... 103 | virtual Dog* clone() const override 104 | { 105 | return new Huskita(*this); 106 | } 107 | }; 108 | struct Poodle : Dog 109 | { 110 | // ... 111 | virtual Dog* clone() const override 112 | { 113 | return new Poodle(*this); 114 | } 115 | }; 116 | 117 | void DogsCollection::copyFrom(const DogsCollection& other) 118 | { 119 | count = other.count; 120 | capacity = other.capacity; 121 | 122 | dogs = new Dog * [capacity]; 123 | for (size_t i = 0; i < count; i++) 124 | { 125 | dogs[i] = other.dogs[i]->clone(); 126 | } 127 | } 128 | 129 | ``` 130 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection/Circle/Circle.cpp: -------------------------------------------------------------------------------- 1 | #include "Circle.h" 2 | 3 | namespace { 4 | const double pi = 3.1415; 5 | } 6 | 7 | Circle::Circle(int x, int y, double radius) : Shape(1) 8 | { 9 | this->radius = radius; 10 | setPoint(0, x, y); 11 | } 12 | 13 | double Circle::getArea() const 14 | { 15 | return pi * radius * radius; 16 | } 17 | 18 | double Circle::getPerimeter() const 19 | { 20 | return 2 * pi * radius; 21 | } 22 | 23 | bool Circle::isPointInFigure(int x, int y) const 24 | { 25 | Shape::Point p(x, y); 26 | return p.getDist(getPointAtIndex(0)) <= radius; 27 | } 28 | 29 | Shape* Circle::clone() const 30 | { 31 | return new Circle(*this); 32 | } 33 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection/Circle/Circle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Shape/Shape.h" 3 | 4 | class Circle : public Shape 5 | { 6 | public: 7 | Circle(int x, int y, double radius); 8 | 9 | virtual double getArea() const override; 10 | virtual double getPerimeter() const override; 11 | virtual bool isPointInFigure(int x, int y) const override; 12 | 13 | virtual Shape* clone() const override; 14 | 15 | private: 16 | double radius; 17 | }; 18 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection/Rectangle/Rectangle.cpp: -------------------------------------------------------------------------------- 1 | #include "Rectangle.h" 2 | 3 | Rectangle::Rectangle(int x1, int y1, int x3, int y3) : Shape(4) 4 | { 5 | setPoint(0, x1, y1); 6 | setPoint(1, x3, y1); 7 | setPoint(2, x3, y3); 8 | setPoint(3, x1, y3); 9 | } 10 | 11 | double Rectangle::getArea() const 12 | { 13 | const Point& p1 = getPointAtIndex(0); 14 | const Point& p2 = getPointAtIndex(1); 15 | const Point& p3 = getPointAtIndex(2); 16 | 17 | return p1.getDist(p2) * p2.getDist(p3); 18 | } 19 | 20 | bool Rectangle::isPointInFigure(int x, int y) const 21 | { 22 | Shape::Point p(x, y); 23 | return p.x >= getPointAtIndex(0).x && p.x <= getPointAtIndex(1).x && 24 | p.y >= getPointAtIndex(0).y && p.y <= getPointAtIndex(2).y; 25 | } 26 | 27 | Shape* Rectangle::clone() const 28 | { 29 | return new Rectangle(*this); 30 | } 31 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection/Rectangle/Rectangle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Shape/Shape.h" 3 | 4 | class Rectangle : public Shape 5 | { 6 | public: 7 | Rectangle(int x1, int y1, int x3, int y3); 8 | 9 | virtual double getArea() const override; 10 | virtual bool isPointInFigure(int x, int y) const override; 11 | 12 | virtual Shape* clone() const override; 13 | }; 14 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection/Shape/Shape.cpp: -------------------------------------------------------------------------------- 1 | #include "Shape.h" 2 | #include 3 | 4 | double Shape::getPerimeter() const 5 | { 6 | assert(pointsCount >= 3); 7 | 8 | double perimeter = 0; 9 | for (size_t i = 0; i < pointsCount - 1; i++) 10 | { 11 | perimeter += points[i].getDist(points[i + 1]); 12 | } 13 | perimeter += points[pointsCount - 1].getDist(points[0]); 14 | return perimeter; 15 | } 16 | 17 | void Shape::setPoint(unsigned index, int x, int y) 18 | { 19 | if (index >= pointsCount) 20 | { 21 | throw std::out_of_range("Invalid index!"); 22 | } 23 | points[index] = Point(x, y); 24 | } 25 | 26 | const Shape::Point& Shape::getPointAtIndex(unsigned index) const 27 | { 28 | if (index >= pointsCount) 29 | { 30 | throw std::out_of_range("Invalid index!"); 31 | } 32 | return points[index]; 33 | } 34 | 35 | Shape::Shape(size_t pointsCount) 36 | { 37 | this->pointsCount = pointsCount; 38 | points = new Point[pointsCount]; 39 | } 40 | 41 | Shape::Shape(const Shape& other) 42 | { 43 | copyFrom(other); 44 | } 45 | Shape& Shape::operator=(const Shape& other) 46 | { 47 | if (this != &other) 48 | { 49 | free(); 50 | copyFrom(other); 51 | } 52 | 53 | return *this; 54 | } 55 | Shape::~Shape() 56 | { 57 | free(); 58 | } 59 | 60 | void Shape::copyFrom(const Shape& other) 61 | { 62 | pointsCount = other.pointsCount; 63 | points = new Point[pointsCount]; 64 | for (size_t i = 0; i < pointsCount; i++) 65 | { 66 | points[i] = other.points[i]; 67 | } 68 | } 69 | void Shape::free() 70 | { 71 | delete[] points; 72 | points = nullptr; 73 | } 74 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection/Shape/Shape.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class Shape 6 | { 7 | public: 8 | Shape(size_t pointsCount); 9 | 10 | Shape(const Shape& other); 11 | Shape& operator=(const Shape& other); 12 | virtual ~Shape(); // !! 13 | 14 | void setPoint(unsigned index, int x, int y); 15 | 16 | virtual double getArea() const = 0; // pure virtual 17 | virtual double getPerimeter() const; // non-pure virtual 18 | virtual bool isPointInFigure(int x, int y) const = 0; // pure virtual 19 | 20 | virtual Shape* clone() const = 0; 21 | 22 | protected: 23 | struct Point 24 | { 25 | int x; 26 | int y; 27 | 28 | Point() : Point(0, 0) 29 | {} 30 | Point(int x, int y) : x(x), y(y) 31 | {} 32 | 33 | double getDist(const Point& other) const 34 | { 35 | int distX = x - other.x; 36 | int distY = y - other.y; 37 | 38 | return sqrt(distX * distX + distY * distY); 39 | } 40 | }; 41 | 42 | const Point& getPointAtIndex(unsigned index) const; 43 | 44 | private: 45 | Point* points; 46 | size_t pointsCount; 47 | 48 | void copyFrom(const Shape& other); 49 | void free(); 50 | }; 51 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection/ShapeCollection/ShapeCollection.cpp: -------------------------------------------------------------------------------- 1 | #include "ShapeCollection.h" 2 | #include "../Circle/Circle.h" 3 | #include "../Rectangle/Rectangle.h" 4 | #include "../Triangle/Triangle.h" 5 | #include 6 | 7 | void ShapeCollection::addShape(Shape* shape) 8 | { 9 | if (count == capacity) 10 | { 11 | resize(); 12 | } 13 | shapes[count++] = shape; 14 | } 15 | 16 | void ShapeCollection::addCircle(int x1, int y1, double radius) 17 | { 18 | addShape(new Circle(x1, y1, radius)); 19 | } 20 | void ShapeCollection::addRectangle(int x1, int y1, int x3, int y3) 21 | { 22 | addShape(new Rectangle(x1, y1, x3, y3)); 23 | } 24 | void ShapeCollection::addTriangle(int x1, int y1, int x2, int y2, int x3, int y3) 25 | { 26 | addShape(new Triangle(x1, y1, x2, y2, x3, y3)); 27 | } 28 | 29 | double ShapeCollection::getAreaOfFigureByIndex(unsigned index) const 30 | { 31 | if (index >= count) 32 | { 33 | throw std::out_of_range("Index is out of range!"); 34 | } 35 | return shapes[index]->getArea(); 36 | } 37 | double ShapeCollection::getPerimeterOfFigureByIndex(unsigned index) const 38 | { 39 | if (index >= count) 40 | { 41 | throw std::out_of_range("Index is out of range!"); 42 | } 43 | return shapes[index]->getPerimeter(); 44 | } 45 | double ShapeCollection::getIsPointInFigureByIndex(unsigned index, int x, int y) const 46 | { 47 | if (index >= count) 48 | { 49 | throw std::out_of_range("Index is out of range!"); 50 | } 51 | return shapes[index]->isPointInFigure(x, y); 52 | } 53 | 54 | size_t ShapeCollection::size() const 55 | { 56 | return count; 57 | } 58 | 59 | ShapeCollection::ShapeCollection() 60 | { 61 | shapes = new Shape * [capacity] {nullptr}; 62 | } 63 | ShapeCollection::ShapeCollection(const ShapeCollection& other) 64 | { 65 | copyFrom(other); 66 | } 67 | ShapeCollection& ShapeCollection::operator=(const ShapeCollection& other) 68 | { 69 | if (this != &other) 70 | { 71 | free(); 72 | copyFrom(other); 73 | } 74 | return *this; 75 | } 76 | ShapeCollection::~ShapeCollection() 77 | { 78 | free(); 79 | } 80 | 81 | void ShapeCollection::copyFrom(const ShapeCollection& other) 82 | { 83 | count = other.count; 84 | capacity = other.capacity; 85 | 86 | shapes = new Shape * [capacity]; 87 | for (size_t i = 0; i < count; i++) 88 | { 89 | shapes[i] = other.shapes[i]->clone(); 90 | } 91 | } 92 | void ShapeCollection::free() 93 | { 94 | for (size_t i = 0; i < count; i++) 95 | { 96 | delete shapes[i]; 97 | } 98 | delete[] shapes; 99 | } 100 | void ShapeCollection::resize() 101 | { 102 | Shape** newCollection = new Shape * [capacity *= 2]; 103 | 104 | for (size_t i = 0; i < count; i++) 105 | { 106 | newCollection[i] = shapes[i]; 107 | } 108 | 109 | delete[] shapes; 110 | shapes = newCollection; 111 | } 112 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection/ShapeCollection/ShapeCollection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Shape/Shape.h" 3 | 4 | class ShapeCollection 5 | { 6 | public: 7 | ShapeCollection(); 8 | ShapeCollection(const ShapeCollection& other); 9 | ShapeCollection& operator=(const ShapeCollection& other); 10 | ~ShapeCollection(); 11 | 12 | void addCircle(int x1, int y1, double radius); 13 | void addRectangle(int x1, int y1, int x3, int y3); 14 | void addTriangle(int x1, int y1, int x2, int y2, int x3, int y3); 15 | 16 | double getAreaOfFigureByIndex(unsigned index) const; 17 | double getPerimeterOfFigureByIndex(unsigned index) const; 18 | double getIsPointInFigureByIndex(unsigned index, int x, int y) const; 19 | 20 | size_t size() const; 21 | 22 | private: 23 | Shape** shapes; 24 | size_t count = 0; 25 | size_t capacity = 8; 26 | 27 | void copyFrom(const ShapeCollection& other); 28 | void free(); 29 | void resize(); 30 | 31 | void addShape(Shape* shape); 32 | }; 33 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "ShapeCollection/ShapeCollection.h" 2 | 3 | int main() 4 | { 5 | ShapeCollection shapeCollection; 6 | 7 | shapeCollection.addCircle(3, 4, 1); 8 | shapeCollection.addRectangle(1, 1, 9, 9); 9 | shapeCollection.addTriangle(1, 2, 9, 4, 0, 0); 10 | 11 | std::cout << "Perimeters of the figures:" << std::endl; 12 | for (size_t i = 0; i < shapeCollection.size(); i++) 13 | { 14 | std::cout << "Figure " << i << ": " << shapeCollection.getPerimeterOfFigureByIndex(i) << std::endl; 15 | } 16 | std::cout << std::endl << "Areas of the figures:" << std::endl; 17 | for (size_t i = 0; i < shapeCollection.size(); i++) 18 | { 19 | std::cout << "Figure " << i << ": " << shapeCollection.getAreaOfFigureByIndex(i) << std::endl; 20 | } 21 | std::cout << std::endl << "Check if point (3,3) is in figure i:" << std::endl; 22 | for (size_t i = 0; i < shapeCollection.size(); i++) 23 | { 24 | std::cout << "Figure " << i << ": " << shapeCollection.getIsPointInFigureByIndex(i, 3, 3) << std::endl; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection/Triangle/Triangle.cpp: -------------------------------------------------------------------------------- 1 | #include "Triangle.h" 2 | 3 | Triangle::Triangle(int x1, int y1, int x2, int y2, int x3, int y3) : Shape(3) 4 | { 5 | setPoint(0, x1, y1); 6 | setPoint(1, x2, y2); 7 | setPoint(2, x3, y3); 8 | } 9 | 10 | double Triangle::getArea() const 11 | { 12 | const Point& p1 = getPointAtIndex(0); 13 | const Point& p2 = getPointAtIndex(1); 14 | const Point& p3 = getPointAtIndex(2); 15 | 16 | double semiPer = getPerimeter() / 2; 17 | return sqrt(semiPer * (semiPer - p1.getDist(p2)) * (semiPer - p2.getDist(p3)) * (semiPer - p3.getDist(p1))); 18 | } 19 | 20 | bool Triangle::isPointInFigure(int x, int y) const 21 | { 22 | Shape::Point p(x, y); 23 | Triangle t1(getPointAtIndex(0).x, getPointAtIndex(0).y, getPointAtIndex(1).x, getPointAtIndex(1).y, p.x, p.y); 24 | Triangle t2(getPointAtIndex(2).x, getPointAtIndex(2).y, getPointAtIndex(1).x, getPointAtIndex(1).y, p.x, p.y); 25 | Triangle t3(getPointAtIndex(2).x, getPointAtIndex(2).y, getPointAtIndex(0).x, getPointAtIndex(0).y, p.x, p.y); 26 | return abs(t1.getArea() + t2.getArea() + t3.getArea() - getArea()) <= std::numeric_limits::epsilon(); 27 | } 28 | 29 | Shape* Triangle::clone() const 30 | { 31 | return new Triangle(*this); 32 | } 33 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection/Triangle/Triangle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Shape/Shape.h" 3 | 4 | class Triangle : public Shape 5 | { 6 | public: 7 | Triangle(int x1, int y1, int x2, int y2, int x3, int y3); 8 | 9 | virtual double getArea() const override; 10 | virtual bool isPointInFigure(int x, int y) const override; 11 | 12 | virtual Shape* clone() const override; 13 | }; 14 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection_FactoryMethod/Circle/Circle.cpp: -------------------------------------------------------------------------------- 1 | #include "Circle.h" 2 | 3 | namespace { 4 | const double pi = 3.1415; 5 | } 6 | 7 | Circle::Circle(int x, int y, double radius) : Shape(1, getCircleType()) 8 | { 9 | this->radius = radius; 10 | setPoint(0, x, y); 11 | } 12 | 13 | double Circle::getArea() const 14 | { 15 | return pi * radius * radius; 16 | } 17 | 18 | double Circle::getPerimeter() const 19 | { 20 | return 2 * pi * radius; 21 | } 22 | 23 | bool Circle::isPointInFigure(int x, int y) const 24 | { 25 | Shape::Point p(x, y); 26 | return p.getDist(getPointAtIndex(0)) <= radius; 27 | } 28 | 29 | Shape* Circle::clone() const 30 | { 31 | return new Circle(*this); 32 | } 33 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection_FactoryMethod/Circle/Circle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Shape/Shape.h" 3 | 4 | class Circle : public Shape 5 | { 6 | public: 7 | Circle(int x, int y, double radius); 8 | 9 | virtual double getArea() const override; 10 | virtual double getPerimeter() const override; 11 | virtual bool isPointInFigure(int x, int y) const override; 12 | 13 | virtual Shape* clone() const override; 14 | 15 | constexpr static int getCircleType() 16 | { 17 | return 1; 18 | } 19 | 20 | private: 21 | double radius; 22 | }; 23 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection_FactoryMethod/Rectangle/Rectangle.cpp: -------------------------------------------------------------------------------- 1 | #include "Rectangle.h" 2 | 3 | Rectangle::Rectangle(int x1, int y1, int x3, int y3) : Shape(4, getRectangleType()) 4 | { 5 | setPoint(0, x1, y1); 6 | setPoint(1, x3, y1); 7 | setPoint(2, x3, y3); 8 | setPoint(3, x1, y3); 9 | } 10 | 11 | double Rectangle::getArea() const 12 | { 13 | const Point& p1 = getPointAtIndex(0); 14 | const Point& p2 = getPointAtIndex(1); 15 | const Point& p3 = getPointAtIndex(2); 16 | 17 | return p1.getDist(p2) * p2.getDist(p3); 18 | } 19 | 20 | bool Rectangle::isPointInFigure(int x, int y) const 21 | { 22 | Shape::Point p(x, y); 23 | return p.x >= getPointAtIndex(0).x && p.x <= getPointAtIndex(1).x && 24 | p.y >= getPointAtIndex(0).y && p.y <= getPointAtIndex(2).y; 25 | } 26 | 27 | Shape* Rectangle::clone() const 28 | { 29 | return new Rectangle(*this); 30 | } 31 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection_FactoryMethod/Rectangle/Rectangle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Shape/Shape.h" 3 | 4 | class Rectangle : public Shape 5 | { 6 | public: 7 | Rectangle(int x1, int y1, int x3, int y3); 8 | 9 | virtual double getArea() const override; 10 | virtual bool isPointInFigure(int x, int y) const override; 11 | 12 | virtual Shape* clone() const override; 13 | 14 | constexpr static int getRectangleType() 15 | { 16 | return 3; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection_FactoryMethod/Shape/Shape.cpp: -------------------------------------------------------------------------------- 1 | #include "Shape.h" 2 | #include 3 | 4 | double Shape::getPerimeter() const 5 | { 6 | assert(pointsCount >= 3); 7 | 8 | double perimeter = 0; 9 | for (size_t i = 0; i < pointsCount - 1; i++) 10 | { 11 | perimeter += points[i].getDist(points[i + 1]); 12 | } 13 | perimeter += points[pointsCount - 1].getDist(points[0]); 14 | return perimeter; 15 | } 16 | 17 | void Shape::setPoint(unsigned index, int x, int y) 18 | { 19 | if (index >= pointsCount) 20 | { 21 | throw std::out_of_range("Invalid index!"); 22 | } 23 | points[index] = Point(x, y); 24 | } 25 | 26 | const Shape::Point& Shape::getPointAtIndex(unsigned index) const 27 | { 28 | if (index >= pointsCount) 29 | { 30 | throw std::out_of_range("Invalid index!"); 31 | } 32 | return points[index]; 33 | } 34 | 35 | int Shape::getShapeType() const 36 | { 37 | return shapeType; 38 | } 39 | 40 | Shape::Shape(size_t pointsCount, int shapeType) 41 | { 42 | this->pointsCount = pointsCount; 43 | points = new Point[pointsCount]; 44 | this->shapeType = shapeType; 45 | } 46 | 47 | Shape::Shape(const Shape& other) 48 | { 49 | copyFrom(other); 50 | } 51 | Shape& Shape::operator=(const Shape& other) 52 | { 53 | if (this != &other) 54 | { 55 | free(); 56 | copyFrom(other); 57 | } 58 | 59 | return *this; 60 | } 61 | Shape::~Shape() 62 | { 63 | free(); 64 | } 65 | 66 | void Shape::copyFrom(const Shape& other) 67 | { 68 | pointsCount = other.pointsCount; 69 | points = new Point[pointsCount]; 70 | for (size_t i = 0; i < pointsCount; i++) 71 | { 72 | points[i] = other.points[i]; 73 | } 74 | shapeType = other.shapeType; 75 | } 76 | void Shape::free() 77 | { 78 | delete[] points; 79 | points = nullptr; 80 | } 81 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection_FactoryMethod/Shape/Shape.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class Shape 6 | { 7 | public: 8 | Shape(size_t pointsCount, int shapeType); 9 | 10 | Shape(const Shape& other); 11 | Shape& operator=(const Shape& other); 12 | virtual ~Shape(); // !! 13 | 14 | void setPoint(unsigned index, int x, int y); 15 | 16 | virtual double getArea() const = 0; // pure virtual 17 | virtual double getPerimeter() const; // non-pure virtual 18 | virtual bool isPointInFigure(int x, int y) const = 0; // pure virtual 19 | 20 | virtual Shape* clone() const = 0; 21 | 22 | int getShapeType() const; 23 | 24 | protected: 25 | struct Point 26 | { 27 | int x; 28 | int y; 29 | 30 | Point() : Point(0, 0) 31 | {} 32 | Point(int x, int y) : x(x), y(y) 33 | {} 34 | 35 | double getDist(const Point& other) const 36 | { 37 | int distX = x - other.x; 38 | int distY = y - other.y; 39 | 40 | return sqrt(distX * distX + distY * distY); 41 | } 42 | }; 43 | 44 | const Point& getPointAtIndex(unsigned index) const; 45 | 46 | private: 47 | Point* points; 48 | size_t pointsCount; 49 | 50 | int shapeType; 51 | 52 | void copyFrom(const Shape& other); 53 | void free(); 54 | }; 55 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection_FactoryMethod/ShapeCollection/ShapeCollection.cpp: -------------------------------------------------------------------------------- 1 | #include "ShapeCollection.h" 2 | #include "../ShapeFactory/ShapeFactory.h" 3 | #include 4 | 5 | bool ShapeCollection::addShape(int shapeType) 6 | { 7 | Shape* newShape = ShapeFactory::createShape(shapeType); 8 | if (newShape) 9 | { 10 | if (count == capacity) 11 | { 12 | resize(); 13 | } 14 | shapes[count++] = newShape; 15 | } 16 | return newShape; 17 | } 18 | 19 | double ShapeCollection::getAreaOfFigureByIndex(unsigned index) const 20 | { 21 | if (index >= count) 22 | { 23 | throw std::out_of_range("Index is out of range!"); 24 | } 25 | return shapes[index]->getArea(); 26 | } 27 | double ShapeCollection::getPerimeterOfFigureByIndex(unsigned index) const 28 | { 29 | if (index >= count) 30 | { 31 | throw std::out_of_range("Index is out of range!"); 32 | } 33 | return shapes[index]->getPerimeter(); 34 | } 35 | double ShapeCollection::getIsPointInFigureByIndex(unsigned index, int x, int y) const 36 | { 37 | if (index >= count) 38 | { 39 | throw std::out_of_range("Index is out of range!"); 40 | } 41 | return shapes[index]->isPointInFigure(x, y); 42 | } 43 | 44 | int ShapeCollection::getShapeTypeByIndex(unsigned index) const 45 | { 46 | if (index >= count) 47 | { 48 | throw std::out_of_range("Index is out of range!"); 49 | } 50 | return shapes[index]->getShapeType(); 51 | } 52 | 53 | size_t ShapeCollection::size() const 54 | { 55 | return count; 56 | } 57 | 58 | ShapeCollection::ShapeCollection() 59 | { 60 | shapes = new Shape * [capacity] {nullptr}; 61 | } 62 | ShapeCollection::ShapeCollection(const ShapeCollection& other) 63 | { 64 | copyFrom(other); 65 | } 66 | ShapeCollection& ShapeCollection::operator=(const ShapeCollection& other) 67 | { 68 | if (this != &other) 69 | { 70 | free(); 71 | copyFrom(other); 72 | } 73 | return *this; 74 | } 75 | ShapeCollection::~ShapeCollection() 76 | { 77 | free(); 78 | } 79 | 80 | void ShapeCollection::copyFrom(const ShapeCollection& other) 81 | { 82 | count = other.count; 83 | capacity = other.capacity; 84 | 85 | shapes = new Shape * [capacity]; 86 | for (size_t i = 0; i < count; i++) 87 | { 88 | shapes[i] = other.shapes[i]->clone(); 89 | } 90 | } 91 | void ShapeCollection::free() 92 | { 93 | for (size_t i = 0; i < count; i++) 94 | { 95 | delete shapes[i]; 96 | } 97 | delete[] shapes; 98 | } 99 | void ShapeCollection::resize() 100 | { 101 | Shape** newCollection = new Shape * [capacity *= 2]; 102 | 103 | for (size_t i = 0; i < count; i++) 104 | { 105 | newCollection[i] = shapes[i]; 106 | } 107 | 108 | delete[] shapes; 109 | shapes = newCollection; 110 | } 111 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection_FactoryMethod/ShapeCollection/ShapeCollection.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Shape/Shape.h" 3 | 4 | class ShapeCollection 5 | { 6 | public: 7 | ShapeCollection(); 8 | ShapeCollection(const ShapeCollection& other); 9 | ShapeCollection& operator=(const ShapeCollection& other); 10 | ~ShapeCollection(); 11 | 12 | bool addShape(int shapeType); 13 | 14 | double getAreaOfFigureByIndex(unsigned index) const; 15 | double getPerimeterOfFigureByIndex(unsigned index) const; 16 | double getIsPointInFigureByIndex(unsigned index, int x, int y) const; 17 | 18 | int getShapeTypeByIndex(unsigned index) const; 19 | 20 | size_t size() const; 21 | 22 | private: 23 | Shape** shapes; 24 | size_t count = 0; 25 | size_t capacity = 8; 26 | 27 | void copyFrom(const ShapeCollection& other); 28 | void free(); 29 | void resize(); 30 | }; 31 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection_FactoryMethod/ShapeFactory/ShapeFactory.cpp: -------------------------------------------------------------------------------- 1 | #include "ShapeFactory.h" 2 | #include "../Circle/Circle.h" 3 | #include "../Triangle/Triangle.h" 4 | #include "../Rectangle/Rectangle.h" 5 | 6 | Shape* ShapeFactory::createShape(int shapeType) 7 | { 8 | switch (shapeType) 9 | { 10 | case Circle::getCircleType(): 11 | { 12 | std::cout << "Enter data for Circle:" << std::endl; 13 | int x, y; 14 | double radius; 15 | std::cin >> x >> y >> radius; 16 | return new Circle(x, y, radius); 17 | } 18 | case Triangle::getTriangleType(): 19 | { 20 | std::cout << "Enter data for Triangle:" << std::endl; 21 | int x1, y1, x2, y2, x3, y3; 22 | std::cin >> x1 >> y1 >> x2 >> y2 >> x3 >> y3; 23 | return new Triangle(x1, y1, x2, y2, x3, y3); 24 | } 25 | case Rectangle::getRectangleType(): 26 | { 27 | std::cout << "Enter data for Rectangle:" << std::endl; 28 | int x1, y1, x3, y3; 29 | std::cin >> x1 >> y1 >> x3 >> y3; 30 | return new Rectangle(x1, y1, x3, y3); 31 | } 32 | default: 33 | return nullptr; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection_FactoryMethod/ShapeFactory/ShapeFactory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Shape/Shape.h" 3 | 4 | class ShapeFactory 5 | { 6 | public: 7 | static Shape* createShape(int shapeType); 8 | }; 9 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection_FactoryMethod/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "ShapeCollection/ShapeCollection.h" 2 | 3 | int main() 4 | { 5 | ShapeCollection coll; 6 | 7 | while (true) 8 | { 9 | std::cout << std::endl << "Enter shape type: " << std::endl; 10 | int shapeType; 11 | std::cin >> shapeType; 12 | 13 | bool result = coll.addShape(shapeType); 14 | 15 | if (result) 16 | { 17 | #ifdef _WIN32 18 | system("cls"); 19 | #else 20 | system("clear"); 21 | #endif 22 | 23 | std::cout << "Current number of shapes in the collection: " << coll.size() << std::endl; 24 | 25 | std::cout << "Their areas:" << std::endl; 26 | for (size_t i = 0; i < coll.size(); i++) 27 | { 28 | std::cout << coll.getAreaOfFigureByIndex(i) << std::endl; 29 | } 30 | } 31 | else 32 | { 33 | std::cout << "Invalid shape type!" << std::endl; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection_FactoryMethod/Triangle/Triangle.cpp: -------------------------------------------------------------------------------- 1 | #include "Triangle.h" 2 | 3 | Triangle::Triangle(int x1, int y1, int x2, int y2, int x3, int y3) : Shape(3, getTriangleType()) 4 | { 5 | setPoint(0, x1, y1); 6 | setPoint(1, x2, y2); 7 | setPoint(2, x3, y3); 8 | } 9 | 10 | double Triangle::getArea() const 11 | { 12 | const Point& p1 = getPointAtIndex(0); 13 | const Point& p2 = getPointAtIndex(1); 14 | const Point& p3 = getPointAtIndex(2); 15 | 16 | double semiPer = getPerimeter() / 2; 17 | return sqrt(semiPer * (semiPer - p1.getDist(p2)) * (semiPer - p2.getDist(p3)) * (semiPer - p3.getDist(p1))); 18 | } 19 | 20 | bool Triangle::isPointInFigure(int x, int y) const 21 | { 22 | Shape::Point p(x, y); 23 | Triangle t1(getPointAtIndex(0).x, getPointAtIndex(0).y, getPointAtIndex(1).x, getPointAtIndex(1).y, p.x, p.y); 24 | Triangle t2(getPointAtIndex(2).x, getPointAtIndex(2).y, getPointAtIndex(1).x, getPointAtIndex(1).y, p.x, p.y); 25 | Triangle t3(getPointAtIndex(2).x, getPointAtIndex(2).y, getPointAtIndex(0).x, getPointAtIndex(0).y, p.x, p.y); 26 | return abs(t1.getArea() + t2.getArea() + t3.getArea() - getArea()) <= std::numeric_limits::epsilon(); 27 | } 28 | 29 | Shape* Triangle::clone() const 30 | { 31 | return new Triangle(*this); 32 | } 33 | -------------------------------------------------------------------------------- /Sem_12/ShapeCollection_FactoryMethod/Triangle/Triangle.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Shape/Shape.h" 3 | 4 | class Triangle : public Shape 5 | { 6 | public: 7 | Triangle(int x1, int y1, int x2, int y2, int x3, int y3); 8 | 9 | virtual double getArea() const override; 10 | virtual bool isPointInFigure(int x, int y) const override; 11 | 12 | virtual Shape* clone() const override; 13 | 14 | constexpr static int getTriangleType() 15 | { 16 | return 2; 17 | } 18 | }; 19 | -------------------------------------------------------------------------------- /Sem_13/Bjarne Stroustrup – Multiple Inheritance for C++.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_13/Bjarne Stroustrup – Multiple Inheritance for C++.pdf -------------------------------------------------------------------------------- /Sem_13/images/ConstrDestr-Multiple_Inheritance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_13/images/ConstrDestr-Multiple_Inheritance.png -------------------------------------------------------------------------------- /Sem_13/images/Diamond.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_13/images/Diamond.jpg -------------------------------------------------------------------------------- /Sem_13/images/Multiple_Inheritance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_13/images/Multiple_Inheritance.png -------------------------------------------------------------------------------- /Sem_13/images/Multiple_Inheritance1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_13/images/Multiple_Inheritance1.png -------------------------------------------------------------------------------- /Sem_13/images/Multiple_Inheritance2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_13/images/Multiple_Inheritance2.png -------------------------------------------------------------------------------- /Sem_14/FunctionAverage/FunctionFromFile.hpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | class FunctionFromFile 4 | { 5 | public: 6 | static unsigned getFileSize(std::ifstream& ifs) 7 | { 8 | size_t currentPos = ifs.tellg(); 9 | ifs.seekg(0, std::ios::end); 10 | size_t fileSize = ifs.tellg(); 11 | ifs.seekg(currentPos); 12 | return fileSize; 13 | } 14 | 15 | FunctionFromFile(const char* filePath) 16 | { 17 | load(filePath); 18 | } 19 | 20 | int operator()(int x) const 21 | { 22 | for (size_t i = 0; i < size; i++) 23 | { 24 | if (x == data[i]) 25 | { 26 | return x; 27 | } 28 | } 29 | return 0; 30 | } 31 | 32 | bool good() const 33 | { 34 | return loaded; 35 | } 36 | 37 | FunctionFromFile(const FunctionFromFile& other) 38 | { 39 | copyFrom(other); 40 | } 41 | 42 | FunctionFromFile& operator=(const FunctionFromFile& other) 43 | { 44 | if (this != &other) 45 | { 46 | free(); 47 | copyFrom(other); 48 | } 49 | return *this; 50 | } 51 | 52 | ~FunctionFromFile() 53 | { 54 | free(); 55 | } 56 | 57 | private: 58 | int* data = nullptr; 59 | size_t size = 0; 60 | bool loaded = false; 61 | 62 | void load(const char* filePath) 63 | { 64 | std::ifstream ifs(filePath, std::ios::binary); 65 | if (!ifs.is_open()) 66 | { 67 | return; 68 | } 69 | 70 | loaded = true; 71 | size = getFileSize(ifs); 72 | data = new int[size]; 73 | ifs.read(reinterpret_cast(data), size * sizeof(int)); 74 | } 75 | 76 | void copyFrom(const FunctionFromFile& other) 77 | { 78 | size = other.size; 79 | data = new int[size]{}; 80 | for (size_t i = 0; i < size; i++) 81 | { 82 | data[i] = other.data[i]; 83 | } 84 | } 85 | 86 | void free() 87 | { 88 | delete[] data; 89 | } 90 | }; -------------------------------------------------------------------------------- /Sem_14/FunctionAverage/IntFunctionAverage.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template 4 | class IntFunctionAverage 5 | { 6 | public: 7 | IntFunctionAverage(const FunctionOne& firstFunc, const FunctionTwo& secondFunc) : firstFunc(firstFunc), secondFunc(secondFunc) 8 | {} 9 | 10 | double average(int x) const 11 | { 12 | return (firstFunc(x) + secondFunc(x)) / 2.0; 13 | } 14 | 15 | private: 16 | FunctionOne firstFunc; 17 | FunctionTwo secondFunc; 18 | }; -------------------------------------------------------------------------------- /Sem_14/FunctionAverage/Source.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "IntFunctionAverage.hpp" 3 | #include "FunctionFromFile.hpp" 4 | 5 | int main() 6 | { 7 | char filePath[1024]{}; 8 | std::cout << "Enter file path:" << std::endl; 9 | std::cin.getline(filePath, 1024); 10 | 11 | FunctionFromFile func(filePath); 12 | if (!func.good()) 13 | { 14 | std::cout << "Invalid file path" << std::endl; 15 | return -1; 16 | } 17 | 18 | IntFunctionAverage f(func, [](int x) { return x; }); 19 | 20 | while (true) 21 | { 22 | int num = 0; 23 | std::cout << "Enter value for the functions:" << std::endl; 24 | std::cin >> num; 25 | std::cout << "Average: " << f.average(num) << std::endl; 26 | } 27 | } -------------------------------------------------------------------------------- /Sem_14/FunctionAverage/test.dat: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /Sem_14/Optional/Optional.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | template 5 | class Optional 6 | { 7 | private: 8 | T* data; 9 | 10 | void copyFrom(const Optional& other); 11 | void free(); 12 | 13 | public: 14 | Optional(const T& data); 15 | 16 | Optional(); 17 | Optional(const Optional& other); 18 | Optional& operator=(const Optional& other); 19 | ~Optional(); 20 | 21 | bool has_value() const; 22 | const T& value() const; 23 | void setData(const T& data); 24 | void reset(); 25 | }; 26 | 27 | template 28 | Optional::Optional(const T& data) 29 | { 30 | setData(data); 31 | } 32 | 33 | template 34 | bool Optional::has_value() const 35 | { 36 | return data != nullptr; 37 | } 38 | template 39 | const T& Optional::value() const 40 | { 41 | if (!has_value()) 42 | { 43 | throw std::logic_error("No data"); 44 | } 45 | 46 | return *data; 47 | } 48 | template 49 | void Optional::setData(const T& data) 50 | { 51 | free(); 52 | this->data = new T(data); 53 | } 54 | template 55 | void Optional::reset() 56 | { 57 | free(); 58 | data = nullptr; 59 | } 60 | 61 | template 62 | Optional::Optional() : data(nullptr) 63 | {} 64 | template 65 | Optional::Optional(const Optional& other) 66 | { 67 | copyFrom(other); 68 | } 69 | template 70 | Optional& Optional::operator=(const Optional& other) 71 | { 72 | if (this != &other) 73 | { 74 | free(); 75 | copyFrom(other); 76 | } 77 | return *this; 78 | } 79 | template 80 | Optional::~Optional() 81 | { 82 | free(); 83 | } 84 | 85 | template 86 | void Optional::copyFrom(const Optional& other) 87 | { 88 | if (other.has_value()) 89 | { 90 | data = new T(*other.data); 91 | } 92 | else 93 | { 94 | data = nullptr; 95 | } 96 | } 97 | template 98 | void Optional::free() 99 | { 100 | delete data; 101 | } 102 | -------------------------------------------------------------------------------- /Sem_14/Pair/Pair.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | template 5 | class Pair 6 | { 7 | private: 8 | T1 first; 9 | T2 second; 10 | 11 | public: 12 | Pair() = default; 13 | Pair(const T1& first, const T2& second); 14 | 15 | void setFirst(const T1& first); 16 | void setSecond(const T2& second); 17 | 18 | const T1& getFirst() const; 19 | const T2& getSecond() const; 20 | }; 21 | 22 | template 23 | Pair::Pair(const T1& first, const T2& second) : first(first), second(second) 24 | {} 25 | 26 | template 27 | void Pair::setFirst(const T1& first) 28 | { 29 | this->first = first; 30 | } 31 | template 32 | void Pair::setSecond(const T2& second) 33 | { 34 | this->second = second; 35 | } 36 | 37 | template 38 | const T1& Pair::getFirst() const 39 | { 40 | return first; 41 | } 42 | template 43 | const T2& Pair::getSecond() const 44 | { 45 | return second; 46 | } 47 | -------------------------------------------------------------------------------- /Sem_14/README.md: -------------------------------------------------------------------------------- 1 | # Шаблони (templates) 2 | 3 | **Какво е шаблон?** 4 | Функция или клас, която/който работи не с променливи от конкретно дефиниран тип, а с абстрактни променливи, се нарича шаблонна функция/клас. 5 | 6 | **Пример:** 7 | ```c++ 8 | template 9 | const T& myMax(const T& lhs, const T& rhs) 10 | { 11 | return lhs < rhs ? rhs : lhs; 12 | } 13 | 14 | int main() 15 | { 16 | std::cout << myMax(24, 22); 17 | } 18 | ``` 19 | 20 | Компилаторът генерира т. нар. шаблонна функция като замества параметрите на шаблона с типовете на съответните фактически параметри. 21 | 22 | :bangbang: Не можем да разделяме шаблонни класове в .h и .cpp файлове. **Трябва да пишем декларацията и дефиницията им в един файл** – например .hpp файл. Причината е следната: 23 | 24 | Да си представим, че имаме следната структура: 25 | ```c++ 26 | template 27 | struct Foo 28 | { 29 | T bar; 30 | void doSomething(const T& param); 31 | }; 32 | ``` 33 | Създаваме инстанция от тази структура: 34 | ```c++ 35 | int main() 36 | { 37 | Foo f; 38 | } 39 | ``` 40 | След като "прочете" този ред, компилаторът ще създаде следния клас: 41 | ```c++ 42 | struct Foo 43 | { 44 | int bar; 45 | void doSomething(const int& param); 46 | }; 47 | ``` 48 | Съответният .cpp файл "не разбира" за създаването на този хедър и кодът не се компилира. 49 | 50 | Ако предварително знаем с какви конкретни типове ще бъде инстанциран шаблонният клас, то можем да заобиколим този проблем като накрая на .cpp файла добавим: 51 | ```c++ 52 | template struct Foo; 53 | template struct Foo; 54 | // ... 55 | ``` 56 | 57 | ## Специализация на шаблони 58 | ```c++ 59 | template 60 | void sort(T* arr, size_t size) 61 | { 62 | // code to implement Quick Sort 63 | } 64 | 65 | // specialized for char data type 66 | template <> 67 | void sort(char* arr, size_t size) 68 | { 69 | // code to implement Count Sort 70 | } 71 | ``` 72 | 73 | --- 74 | 75 | ## Задача 1: 76 | Реализирайте клас **IntFunctionAverage**, който съдържа: 77 | - Конструктор, който приема две целочислени функции (или обекти, които се държат като такива). 78 | - Метод **average**, който приема цяло число **x** и връща средноаритметичното на двете функции в **x**. 79 | 80 | Да се демонстрира работата на класа с поне следните две функции: 81 | - идентитет 82 | - функция (обект-функция), която "чете" съдържанието на файл с цели числа. Функцията приема цяло число **x** и връща **х**, ако **х** е число от файла, и 0, в противен случай. 83 | ❗❗Не трябва в тялото на функцията да се отваря и чете от файл. Четенето трябва да се случи веднъж, а не при всяко извикване на функцията. 84 | 85 | ## Задача 2: 86 | SetsTask.pdf 87 | -------------------------------------------------------------------------------- /Sem_14/SetsTask.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_14/SetsTask.pdf -------------------------------------------------------------------------------- /Sem_14/SharedPtr/SharedPtr.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | template 5 | class SharedPtr 6 | { 7 | private: 8 | T* data; 9 | size_t* ptrCount; 10 | 11 | void copyFrom(const SharedPtr& other); 12 | void free(); 13 | 14 | public: 15 | SharedPtr(); 16 | SharedPtr(T* data); 17 | 18 | SharedPtr(const SharedPtr& other); 19 | SharedPtr& operator=(const SharedPtr& other); 20 | ~SharedPtr(); 21 | 22 | const T& operator*() const; 23 | T& operator*(); 24 | const T* operator->() const; 25 | T* operator->(); 26 | }; 27 | 28 | template 29 | SharedPtr::SharedPtr() 30 | { 31 | data = nullptr; 32 | ptrCount = nullptr; 33 | } 34 | template 35 | SharedPtr::SharedPtr(T* data) 36 | { 37 | this->data = data; 38 | ptrCount = new size_t(1); 39 | } 40 | 41 | template 42 | SharedPtr::SharedPtr(const SharedPtr& other) 43 | { 44 | copyFrom(other); 45 | } 46 | template 47 | SharedPtr& SharedPtr::operator=(const SharedPtr& other) 48 | { 49 | if (this != &other) 50 | { 51 | free(); 52 | copyFrom(other); 53 | } 54 | return *this; 55 | } 56 | template 57 | SharedPtr::~SharedPtr() 58 | { 59 | free(); 60 | } 61 | 62 | template 63 | const T& SharedPtr::operator*() const 64 | { 65 | if (data == nullptr) 66 | { 67 | throw std::logic_error("Pointer not set"); 68 | } 69 | return *data; 70 | } 71 | template 72 | T& SharedPtr::operator*() 73 | { 74 | if (data == nullptr) 75 | { 76 | throw std::logic_error("Pointer not set"); 77 | } 78 | return *data; 79 | } 80 | 81 | template 82 | const T* SharedPtr::operator->() const 83 | { 84 | return data; 85 | } 86 | template 87 | T* SharedPtr::operator->() 88 | { 89 | return data; 90 | } 91 | 92 | template 93 | void SharedPtr::copyFrom(const SharedPtr& other) 94 | { 95 | data = other.data; 96 | ptrCount = other.ptrCount; 97 | (*ptrCount)++; 98 | } 99 | template 100 | void SharedPtr::free() 101 | { 102 | if (data == nullptr && ptrCount == nullptr) 103 | { 104 | return; 105 | } 106 | if (*ptrCount == 1) 107 | { 108 | delete data, ptrCount; 109 | data = nullptr; 110 | ptrCount = nullptr; 111 | } 112 | else 113 | { 114 | (*ptrCount)--; 115 | } 116 | } -------------------------------------------------------------------------------- /Sem_14/SharedPtr/Source.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "SharedPtr.hpp" 3 | 4 | int main() 5 | { 6 | SharedPtr ptr(new int(5)); 7 | SharedPtr ptr2 = ptr; 8 | std::cout << *ptr << std::endl; 9 | } -------------------------------------------------------------------------------- /Sem_15/BooleanExpressionCalculator/BooleanExpressionHandler.cpp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_15/BooleanExpressionCalculator/BooleanExpressionHandler.cpp -------------------------------------------------------------------------------- /Sem_15/BooleanExpressionCalculator/BooleanExpressionHandler.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_15/BooleanExpressionCalculator/BooleanExpressionHandler.h -------------------------------------------------------------------------------- /Sem_15/BooleanExpressionCalculator/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "BooleanExpressionHandler.h" 2 | 3 | int main() 4 | { 5 | BooleanExpressionHandler expr("((p)|((q)&(t)))"); 6 | 7 | BooleanInterpretation bi; 8 | bi.set('p', true); 9 | std::cout << expr.evaluate(bi) << std::endl; 10 | 11 | BooleanExpressionHandler expr2("((p)|(!(p)))"); 12 | std::cout << expr2.isTautology() << std::endl; 13 | } -------------------------------------------------------------------------------- /Sem_15/Chess/ChessBoard/ChessBoard.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../FigureFactory/FigureFactory.h" 3 | 4 | class ChessBoard 5 | { 6 | private: 7 | const static size_t BOARD_SIZE = 8; 8 | FigureFactory factory; 9 | 10 | struct LastMove 11 | { 12 | unsigned int x, y, destX, destY; 13 | Figure* destFigurePtr = nullptr; 14 | bool canUndo = false; 15 | } lastMove; 16 | 17 | struct Cell 18 | { 19 | Figure* figure = nullptr; 20 | 21 | Cell() = default; 22 | Cell(const Cell& other) = delete; 23 | Cell& operator=(const Cell& other) = delete; 24 | ~Cell() 25 | { 26 | delete figure; 27 | } 28 | 29 | bool isEmpty() const 30 | { 31 | return !figure; 32 | } 33 | void print() const 34 | { 35 | if (figure) 36 | { 37 | figure->print(); 38 | } 39 | else 40 | { 41 | std::cout << ' '; 42 | } 43 | } 44 | }; 45 | Cell board[BOARD_SIZE][BOARD_SIZE]; 46 | 47 | enum class Direction 48 | { 49 | Up, Down, Left, Right, UpLeft, UpRight, DownLeft, DownRight, None 50 | }; 51 | 52 | private: 53 | std::pair getNextPosition(unsigned int x, unsigned int y, Direction direction) const; 54 | Direction getDirection(unsigned int x, unsigned int y, unsigned int destX, unsigned int destY) const; 55 | 56 | bool areAllIntermediateFree(unsigned int x, unsigned int y, unsigned int destX, unsigned int destY) const; 57 | 58 | bool checkIfMovementOfAFigureCanEscapeCheck(unsigned int figureX, unsigned int figureY, bool isWhite); 59 | 60 | void getKingsCoordinates(unsigned int& kingX, unsigned int& kingY, bool isWhite) const; 61 | 62 | void makeAMove(unsigned int x, unsigned int y, unsigned int destX, unsigned int destY); 63 | 64 | public: 65 | ChessBoard(); 66 | 67 | bool isPlayerInCheck(bool isWhite) const; 68 | bool isPlayerInCheckmate(bool isWhite); 69 | 70 | bool isMovable(unsigned int x, unsigned int y, unsigned int destX, unsigned int destY, bool isWhite) const; 71 | bool moveFigure(unsigned int x, unsigned int y, unsigned int destX, unsigned int destY, bool isWhite); 72 | 73 | void undoMove(); 74 | 75 | void print() const; 76 | }; -------------------------------------------------------------------------------- /Sem_15/Chess/FigureFactory/FigureFactory.cpp: -------------------------------------------------------------------------------- 1 | #include "FigureFactory.h" 2 | #include "../Figures/King/King.h" 3 | #include "../Figures/Queen/Queen.h" 4 | #include "../Figures/Bishop/Bishop.h" 5 | #include "../Figures/Knight/Knight.h" 6 | #include "../Figures/Rook/Rook.h" 7 | #include "../Figures/Pawn/Pawn.h" 8 | 9 | Figure* FigureFactory::createFigure(bool isWhite, Figure::FigureType type) const 10 | { 11 | switch (type) 12 | { 13 | case Figure::FigureType::KingFigure: 14 | return new King(isWhite); 15 | case Figure::FigureType::QueenFigure: 16 | return new Queen(isWhite); 17 | case Figure::FigureType::KnightFigure: 18 | return new Knight(isWhite); 19 | case Figure::FigureType::BishopFigure: 20 | return new Bishop(isWhite); 21 | case Figure::FigureType::PawnFigure: 22 | return new Pawn(isWhite); 23 | case Figure::FigureType::RookFigure: 24 | return new Rook(isWhite); 25 | default: 26 | return nullptr; 27 | } 28 | } -------------------------------------------------------------------------------- /Sem_15/Chess/FigureFactory/FigureFactory.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Figures/Figure/Figure.h" 3 | 4 | class FigureFactory 5 | { 6 | public: 7 | Figure* createFigure(bool isWhite, Figure::FigureType type) const; 8 | }; -------------------------------------------------------------------------------- /Sem_15/Chess/Figures/Bishop/Bishop.cpp: -------------------------------------------------------------------------------- 1 | #include "Bishop.h" 2 | #include 3 | 4 | Bishop::Bishop(bool isWhite) : Figure(isWhite, FigureType::BishopFigure) 5 | {} 6 | 7 | bool Bishop::canBeMoved(unsigned int currentX, unsigned int currentY, unsigned int destX, unsigned int destY) const 8 | { 9 | return abs((int)currentX - (int)destX) == abs((int)currentY - (int)destY); 10 | } 11 | void Bishop::print() const 12 | { 13 | getIsWhite() ? std::cout << 'B' : std::cout << 'b'; 14 | } -------------------------------------------------------------------------------- /Sem_15/Chess/Figures/Bishop/Bishop.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Figure/Figure.h" 3 | 4 | class Bishop : public Figure 5 | { 6 | public: 7 | Bishop(bool isWhite); 8 | 9 | virtual bool canBeMoved(unsigned int currentX, unsigned int currentY, unsigned int destX, unsigned int destY) const override; 10 | virtual void print() const override; 11 | }; -------------------------------------------------------------------------------- /Sem_15/Chess/Figures/Figure/Figure.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class Figure 5 | { 6 | public: 7 | enum class FigureType 8 | { 9 | KingFigure, 10 | QueenFigure, 11 | KnightFigure, 12 | BishopFigure, 13 | PawnFigure, 14 | RookFigure 15 | }; 16 | 17 | private: 18 | bool isWhite; 19 | FigureType type; 20 | 21 | public: 22 | Figure(bool isWhite, FigureType type) : isWhite(isWhite), type(type) 23 | {} 24 | 25 | virtual bool canBeMoved(unsigned int currentX, unsigned int currentY, unsigned int destX, unsigned int destY) const = 0; 26 | virtual void print() const = 0; 27 | 28 | bool getIsWhite() const { return isWhite; } 29 | FigureType getType() const { return type; } 30 | 31 | virtual ~Figure() = default; 32 | }; -------------------------------------------------------------------------------- /Sem_15/Chess/Figures/King/King.cpp: -------------------------------------------------------------------------------- 1 | #include "King.h" 2 | #include 3 | 4 | King::King(bool isWhite) : Figure(isWhite, FigureType::KingFigure) 5 | {} 6 | 7 | bool King::canBeMoved(unsigned int currentX, unsigned int currentY, unsigned int destX, unsigned int destY) const 8 | { 9 | return abs((int)currentX - (int)destX) <= 1 && abs((int)currentY - (int)destY) <= 1; 10 | } 11 | void King::print() const 12 | { 13 | getIsWhite() ? std::cout << 'K' : std::cout << 'k'; 14 | } -------------------------------------------------------------------------------- /Sem_15/Chess/Figures/King/King.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Figure/Figure.h" 3 | 4 | class King : public Figure 5 | { 6 | public: 7 | King(bool isWhite); 8 | 9 | virtual bool canBeMoved(unsigned int currentX, unsigned int currentY, unsigned int destX, unsigned int destY) const override; 10 | virtual void print() const override; 11 | }; -------------------------------------------------------------------------------- /Sem_15/Chess/Figures/Knight/Knight.cpp: -------------------------------------------------------------------------------- 1 | #include "Knight.h" 2 | 3 | Knight::Knight(bool isWhite) : Figure(isWhite, FigureType::KnightFigure) 4 | {} 5 | 6 | bool Knight::canBeMoved(unsigned int currentX, unsigned int currentY, unsigned int destX, unsigned int destY) const 7 | { 8 | static const unsigned int allPossibleMoves = 8; 9 | static const int xMovеment[] = { 1, 1, -1, -1, 2, -2, 2, -2 }; 10 | static const int yMovеment[] = { 2, -2, 2, -2, 1, 1, -1, -1 }; 11 | 12 | for (size_t i = 0; i < allPossibleMoves; i++) 13 | { 14 | if (currentX + xMovеment[i] == destX && currentY + yMovеment[i] == destY) 15 | { 16 | return true; 17 | } 18 | } 19 | return false; 20 | } 21 | void Knight::print() const 22 | { 23 | getIsWhite() ? std::cout << 'N' : std::cout << 'n'; 24 | } -------------------------------------------------------------------------------- /Sem_15/Chess/Figures/Knight/Knight.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Figure/Figure.h" 3 | 4 | class Knight : public Figure 5 | { 6 | public: 7 | Knight(bool isWhite); 8 | 9 | virtual bool canBeMoved(unsigned int currentX, unsigned int currentY, unsigned int destX, unsigned int destY) const override; 10 | virtual void print() const override; 11 | }; -------------------------------------------------------------------------------- /Sem_15/Chess/Figures/Pawn/Pawn.cpp: -------------------------------------------------------------------------------- 1 | #include "Pawn.h" 2 | 3 | Pawn::Pawn(bool isWhite) : Figure(isWhite, FigureType::PawnFigure), isFirstMove(true) 4 | {} 5 | 6 | bool Pawn::canBeMoved(unsigned int currentX, unsigned int currentY, unsigned int destX, unsigned int destY) const 7 | { 8 | if (getIsWhite()) 9 | { 10 | return abs((int)currentX - (int)destX) <= 1 + isFirstMove && abs((int)currentY - (int)destY) <= 1; 11 | } 12 | else 13 | { 14 | return abs((int)currentX - (int)destX) <= 1 + isFirstMove && abs((int)currentY - (int)destY) <= 1; 15 | } 16 | } 17 | void Pawn::print() const 18 | { 19 | getIsWhite() ? std::cout << 'P' : std::cout << 'p'; 20 | } 21 | 22 | void Pawn::setIsFirstMove() 23 | { 24 | this->isFirstMove = false; 25 | } -------------------------------------------------------------------------------- /Sem_15/Chess/Figures/Pawn/Pawn.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Figure/Figure.h" 3 | 4 | class Pawn : public Figure 5 | { 6 | private: 7 | mutable bool isFirstMove; 8 | 9 | public: 10 | Pawn(bool isWhite); 11 | 12 | virtual bool canBeMoved(unsigned int currentX, unsigned int currentY, unsigned int destX, unsigned int destY) const override; 13 | virtual void print() const override; 14 | 15 | void setIsFirstMove(); 16 | }; -------------------------------------------------------------------------------- /Sem_15/Chess/Figures/Queen/Queen.cpp: -------------------------------------------------------------------------------- 1 | #include "Queen.h" 2 | #include 3 | 4 | Queen::Queen(bool isWhite) : Figure(isWhite, FigureType::QueenFigure) 5 | {} 6 | 7 | bool Queen::canBeMoved(unsigned int currentX, unsigned int currentY, unsigned int destX, unsigned int destY) const 8 | { 9 | return (abs((int)currentX - (int)destX) == abs((int)currentY - (int)destY)) || (currentX == destX || currentY == destY); 10 | } 11 | void Queen::print() const 12 | { 13 | getIsWhite() ? std::cout << 'Q' : std::cout << 'q'; 14 | } -------------------------------------------------------------------------------- /Sem_15/Chess/Figures/Queen/Queen.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Figure/Figure.h" 3 | 4 | class Queen : public Figure 5 | { 6 | public: 7 | Queen(bool isWhite); 8 | 9 | virtual bool canBeMoved(unsigned int currentX, unsigned int currentY, unsigned int destX, unsigned int destY) const override; 10 | virtual void print() const override; 11 | }; -------------------------------------------------------------------------------- /Sem_15/Chess/Figures/Rook/Rook.cpp: -------------------------------------------------------------------------------- 1 | #include "Rook.h" 2 | 3 | Rook::Rook(bool isWhite) : Figure(isWhite, FigureType::RookFigure) 4 | {} 5 | 6 | bool Rook::canBeMoved(unsigned int currentX, unsigned int currentY, unsigned int destX, unsigned int destY) const 7 | { 8 | return currentX == destX || currentY == destY; 9 | } 10 | void Rook::print() const 11 | { 12 | getIsWhite() ? std::cout << 'R' : std::cout << 'r'; 13 | } -------------------------------------------------------------------------------- /Sem_15/Chess/Figures/Rook/Rook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../Figure/Figure.h" 3 | 4 | class Rook : public Figure 5 | { 6 | public: 7 | Rook(bool isWhite); 8 | 9 | virtual bool canBeMoved(unsigned int currentX, unsigned int currentY, unsigned int destX, unsigned int destY) const override; 10 | virtual void print() const override; 11 | }; -------------------------------------------------------------------------------- /Sem_15/Chess/Source.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Implementation of a chess game including check, checkmate, etc. 3 | * Author: Maria Grozdeva 4 | */ 5 | 6 | #include "ChessBoard/ChessBoard.h" 7 | 8 | int main() 9 | { 10 | ChessBoard chessBoard; 11 | chessBoard.print(); 12 | std::cout << "RULES: " << 13 | "Each player begins the game with sixteen pieces: each player's pieces comprise of one king, one queen, two rooks, two bishops, two knights and eight pawns. " << std::endl << 14 | "One player, referred to as White, controls the white pieces and the other player, Black, controls the black pieces; White is always the first player to move. " << std::endl << 15 | "When a player makes a move, he should write the coordinates of the figure he wants to move and the ones of the square where he wants to put the figure. " << std::endl << 16 | "Coordinates are as follows: x in [1..8], y in [a..h]. Example move: \"2a 4a\"." << std::endl << 17 | "Good luck!" << std::endl; 18 | 19 | bool isWhiteTurn = true; 20 | while (true) 21 | { 22 | std::cout << std::endl << (isWhiteTurn ? "White's turn!" : "Black's turn!") << std::endl; 23 | std::cout << "Enter coordinates: "; 24 | 25 | int x, y, destX, destY; 26 | while (true) 27 | { 28 | std::string fromWhere; 29 | std::string toWhere; 30 | std::cin >> fromWhere >> toWhere; 31 | 32 | x = fromWhere[0] - '1'; 33 | y = fromWhere[1] - 'a'; 34 | destX = toWhere[0] - '1'; 35 | destY = toWhere[1] - 'a'; 36 | 37 | if (x < 0 || y < 0 || x >= 8 || y >= 8 || destX < 0 || destY < 0 || destX >= 8 || destY >= 8 || 38 | (x == destX && y == destY) || 39 | !chessBoard.isMovable(x, y, destX, destY, isWhiteTurn)) 40 | { 41 | std::cout << "Invalid coordinates! Enter again: "; 42 | continue; 43 | } 44 | 45 | bool moved = chessBoard.moveFigure(x, y, destX, destY, isWhiteTurn); 46 | if (!moved) 47 | { 48 | std::cout << "Invalid coordinates! Enter again: "; 49 | continue; 50 | } 51 | 52 | if (chessBoard.isPlayerInCheck(isWhiteTurn)) 53 | { 54 | chessBoard.undoMove(); 55 | std::cout << "Invalid coordinates! You will be in check! Enter again: "; 56 | continue; 57 | } 58 | if (chessBoard.isPlayerInCheck(!isWhiteTurn)) 59 | { 60 | if (chessBoard.isPlayerInCheckmate(!isWhiteTurn)) 61 | { 62 | std::cout << (isWhiteTurn ? "Checkmate, black!" : "Checkmate, white!") << std::endl; 63 | return 0; 64 | } 65 | std::cout << (isWhiteTurn ? "Black, you are in check!" : "White, you are in check!") << std::endl; 66 | } 67 | break; 68 | } 69 | 70 | chessBoard.print(); 71 | isWhiteTurn = !isWhiteTurn; 72 | } 73 | } -------------------------------------------------------------------------------- /Sem_15/README.md: -------------------------------------------------------------------------------- 1 | # Дървовидна структура от полиморфни обекти 2 | 3 | Искаме да реализираме клас за работа с **изрази от множества**. 4 | 5 | Искаме да имаме: 6 | - Функция за парсване на израз от стринг; 7 | - Функция, която приема елемент и връща дали елементът е част от полученото множество; 8 | - Функция, която приема 2 израза и връща дали се получава едно и също множество. 9 | 10 | --- 11 | 12 | ## Представяне в паметта 13 | Всеки израз от множества е: 14 | 15 | - Едно множество (синглетон); 16 | - Унарна операция, която има друг израз от множества; 17 | - Бинарна операция, която има ляв израз от множества и десен израз от множества. 18 | 19 | ![alt_text](https://github.com/MariaGrozdeva/Object-oriented_programming_FMI/blob/main/Sem_15/images/SetExpression_1.png) 20 | 21 | --- 22 | 23 | ## Променливите, участващи в изразите от множества 24 | При построяването на всеки израз ще пазим кои променливи участват. Отново това става по различен начин за трите вида изрази. 25 | 26 | - В множеството от един елемент участва само една променлива (самото множество); 27 | - В унарната операция участват точно тези променливи, които участват в подизраза; 28 | - В бинарната операция участват променливите от левия израз и променливите от десния израз (тяхното обединение). 29 | 30 | ![alt_text](https://github.com/MariaGrozdeva/Object-oriented_programming_FMI/blob/main/Sem_15/images/SetExpression_2.png) 31 | 32 | --- 33 | 34 | ## Създаване на такъв израз по стринг 35 | За да избегнем въвеждането на приоритет и прилагането на алгоритми като Shunting yard, ще записваме изразите със скоби около всяка операция. 36 | Примерен такъв стринг: (((PvQ)^(TvR))v(!P)). 37 | 38 | Как да разберем коя операция се прилага първа? 39 | - Премахваме първата и последната скоба; 40 | - Обхождаме стринга и използваме брояч. При срещането на отваряща скоба увеличаваме брояча с 1, а при срещането на затваряща – намаляваме брояча с 1; 41 | - Символът за операция, който срещнем, когато броячът има стойност 0, е точно операцията, която трябва да се приложи първа. За аргументите на операцията извикваме същатата функция рекурсивно. 42 | 43 | ![alt_text](https://github.com/MariaGrozdeva/Object-oriented_programming_FMI/blob/main/Sem_15/images/SetExpression_3.png) 44 | -------------------------------------------------------------------------------- /Sem_15/SetCalculator/Calculator/SetCalculator.cpp: -------------------------------------------------------------------------------- 1 | #include "SetCalculator.h" 2 | 3 | SetCalculator::SetCalculator(const std::string& str) 4 | { 5 | ptr = parse(str); 6 | } 7 | 8 | bool SetCalculator::isElementIn(const SetExpression::Element& el) const 9 | { 10 | return ptr->isElementIn(el); 11 | } 12 | 13 | SetExpression* SetCalculator::parse(const std::string& str) 14 | { 15 | if (str.size() == 1) 16 | { 17 | return new Singleton(str[0]); 18 | } 19 | 20 | // should be an operation 21 | std::string withoutBrackets = str.substr(1, str.size() - 2); 22 | 23 | size_t count = 0; 24 | for (size_t i = 0; i < withoutBrackets.size(); i++) 25 | { 26 | if (withoutBrackets[i] == '(') 27 | { 28 | count++; 29 | } 30 | else if (withoutBrackets[i] == ')') 31 | { 32 | count--; 33 | } 34 | else if (count == 0 && isOperation(withoutBrackets[i])) 35 | { 36 | if (withoutBrackets[i] == '!') 37 | { 38 | return new UnaryOperation('!', parse(withoutBrackets.substr(i + 1))); 39 | } 40 | else 41 | { 42 | return new BinaryOperation(withoutBrackets[i], parse(withoutBrackets.substr(0, i)), parse(withoutBrackets.substr(i + 1))); 43 | } 44 | } 45 | } 46 | } 47 | bool SetCalculator::isOperation(char ch) const 48 | { 49 | return ch == 'v' || ch == '^' || ch == '\\' || ch == 'x' || ch == '!'; 50 | } 51 | 52 | SetCalculator::SetCalculator(const SetCalculator& other) 53 | { 54 | copyFrom(other); 55 | } 56 | SetCalculator& SetCalculator::operator=(const SetCalculator& other) 57 | { 58 | if (this != &other) 59 | { 60 | free(); 61 | copyFrom(other); 62 | } 63 | 64 | return *this; 65 | } 66 | SetCalculator::~SetCalculator() 67 | { 68 | free(); 69 | } 70 | 71 | void SetCalculator::SetCalculator::copyFrom(const SetCalculator& other) 72 | { 73 | ptr = other.ptr->clone(); 74 | } 75 | void SetCalculator::SetCalculator::free() 76 | { 77 | delete ptr; 78 | } 79 | -------------------------------------------------------------------------------- /Sem_15/SetCalculator/Calculator/SetCalculator.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "SetExpression.h" 3 | #include "Singleton.h" 4 | #include "Operation.h" 5 | #include 6 | 7 | class SetCalculator 8 | { 9 | private: 10 | SetExpression* ptr; 11 | 12 | void copyFrom(const SetCalculator& other); 13 | void free(); 14 | 15 | SetExpression* parse(const std::string& str); 16 | bool isOperation(char ch) const; 17 | 18 | public: 19 | SetCalculator(const SetCalculator& other); 20 | SetCalculator& operator=(const SetCalculator& other); 21 | ~SetCalculator(); 22 | 23 | SetCalculator(const std::string& str); 24 | 25 | bool isElementIn(const SetExpression::Element& el) const; 26 | }; -------------------------------------------------------------------------------- /Sem_15/SetCalculator/Operation.cpp: -------------------------------------------------------------------------------- 1 | #include "Operation.h" 2 | 3 | UnaryOperation::UnaryOperation(char op, SetExpression* sub) : op(op), sub(sub) 4 | {} 5 | 6 | bool UnaryOperation::isElementIn(const Element& el) const 7 | { 8 | switch (op) 9 | { 10 | case '!': return !sub->isElementIn(el); 11 | } 12 | return false; 13 | } 14 | SetExpression* UnaryOperation::clone() const 15 | { 16 | return new UnaryOperation(op, sub->clone()); 17 | } 18 | 19 | UnaryOperation::~UnaryOperation() 20 | { 21 | delete sub; 22 | } 23 | 24 | 25 | BinaryOperation::BinaryOperation(char op, SetExpression* left, SetExpression* right) : op(op), left(left), right(right) 26 | {} 27 | 28 | bool BinaryOperation::isElementIn(const Element& el) const 29 | { 30 | switch (op) 31 | { 32 | case 'v': return left->isElementIn(el) || right->isElementIn(el); 33 | case '^': return left->isElementIn(el) && right->isElementIn(el); 34 | case '\\': return left->isElementIn(el) && !right->isElementIn(el); 35 | case 'x': return (left->isElementIn(el) && !right->isElementIn(el)) || (!left->isElementIn(el) && right->isElementIn(el)); 36 | } 37 | return false; 38 | } 39 | SetExpression* BinaryOperation::clone() const 40 | { 41 | return new BinaryOperation(op, left->clone(), right->clone()); 42 | } 43 | 44 | BinaryOperation::~BinaryOperation() 45 | { 46 | delete left, right; 47 | } -------------------------------------------------------------------------------- /Sem_15/SetCalculator/Operation.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "SetExpression.h" 3 | 4 | class UnaryOperation : public SetExpression 5 | { 6 | private: 7 | char op; 8 | SetExpression* sub; 9 | 10 | public: 11 | UnaryOperation(char op, SetExpression* sub); 12 | 13 | virtual bool isElementIn(const Element& el) const override; 14 | virtual SetExpression* clone() const override; 15 | 16 | virtual ~UnaryOperation(); 17 | }; 18 | 19 | 20 | class BinaryOperation : public SetExpression 21 | { 22 | private: 23 | char op; 24 | SetExpression* left; 25 | SetExpression* right; 26 | 27 | public: 28 | BinaryOperation(char op, SetExpression* left, SetExpression* right); 29 | 30 | virtual bool isElementIn(const Element& el) const override; 31 | virtual SetExpression* clone() const override; 32 | 33 | virtual ~BinaryOperation(); 34 | }; -------------------------------------------------------------------------------- /Sem_15/SetCalculator/SetExpression.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class SetExpression 5 | { 6 | public: 7 | struct Element 8 | { 9 | bool sets[26] = { false }; 10 | 11 | void set(char ch, bool isIn) 12 | { 13 | assert(ch >= 'A' && ch <= 'Z'); 14 | sets[ch - 'A'] = isIn; 15 | } 16 | bool get(char ch) const 17 | { 18 | assert(ch >= 'A' && ch <= 'Z'); 19 | return sets[ch - 'A']; 20 | } 21 | }; 22 | 23 | virtual bool isElementIn(const Element& el) const = 0; 24 | virtual SetExpression* clone() const = 0; 25 | 26 | virtual ~SetExpression() = default; 27 | }; -------------------------------------------------------------------------------- /Sem_15/SetCalculator/Singleton.cpp: -------------------------------------------------------------------------------- 1 | #include "Singleton.h" 2 | 3 | bool Singleton::isElementIn(const Element& el) const 4 | { 5 | return el.get(name); 6 | } 7 | SetExpression* Singleton::clone() const 8 | { 9 | return new Singleton(*this); 10 | } -------------------------------------------------------------------------------- /Sem_15/SetCalculator/Singleton.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "SetExpression.h" 3 | 4 | class Singleton : public SetExpression 5 | { 6 | private: 7 | char name; 8 | 9 | public: 10 | Singleton(char name) : name(name) 11 | {} 12 | 13 | virtual bool isElementIn(const Element& el) const override; 14 | virtual SetExpression* clone() const override; 15 | }; -------------------------------------------------------------------------------- /Sem_15/SetCalculator/Source.cpp: -------------------------------------------------------------------------------- 1 | #include "SetCalculator.h" 2 | #include 3 | 4 | int main() 5 | { 6 | SetCalculator s("(((A^B)vC)vX)"); 7 | 8 | SetExpression::Element el; 9 | el.set('A', true); 10 | el.set('B', true); 11 | el.set('C', true); 12 | 13 | std::cout << s.isElementIn(el); 14 | } -------------------------------------------------------------------------------- /Sem_15/images/SetExpression_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_15/images/SetExpression_1.png -------------------------------------------------------------------------------- /Sem_15/images/SetExpression_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_15/images/SetExpression_2.png -------------------------------------------------------------------------------- /Sem_15/images/SetExpression_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MariaGrozdeva/Object-oriented_programming_FMI/001e59eb55e62c3b569ec7cc9a486b271af10cb5/Sem_15/images/SetExpression_3.png --------------------------------------------------------------------------------