diff --git a/templates/_folder_Lectures/Lecture 15/parallell_2_OOP/Point2D.cpp b/templates/_folder_Lectures/Lecture 15/parallell_2_OOP/Point2D.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4036014250ae6cf4e559e38cbe534908fe3f81e8 --- /dev/null +++ b/templates/_folder_Lectures/Lecture 15/parallell_2_OOP/Point2D.cpp @@ -0,0 +1,14 @@ +#include <iostream> +#include "Point2D.h" + +void Point2D::printCoordinates() { + std::cout << "Two coordinates: " << "(" << coord1 << ", " << coord2 << ")" << std::endl; +} + +void CartesianPoint2D::printCoordinates() { + std::cout << "Cartesian coordinates: " << "(x=" << coord1 << ", y=" << coord2 << ")" << std::endl; +} + +void PolarPoint2D::printCoordinates() { + std::cout << "Polar coordinates: " << "(radius=" << coord1 << ", angle=" << coord2 << ")" << std::endl; +} diff --git a/templates/_folder_Lectures/Lecture 15/parallell_2_OOP/Point2D.h b/templates/_folder_Lectures/Lecture 15/parallell_2_OOP/Point2D.h new file mode 100644 index 0000000000000000000000000000000000000000..4332f30d52423c118bcc965e3ac6d885e924b9da --- /dev/null +++ b/templates/_folder_Lectures/Lecture 15/parallell_2_OOP/Point2D.h @@ -0,0 +1,26 @@ +#pragma once + +class Point2D { +protected: + int coord1; + int coord2; +public: + Point2D(int a, int b) : coord1{a}, coord2{b} {} + Point2D() : coord1{0}, coord2{0} {} + ~Point2D() {} + void printCoordinates(); +}; + +class CartesianPoint2D : public Point2D { +public: + CartesianPoint2D() : Point2D() {} + CartesianPoint2D(int a, int b) : Point2D(a, b) {} + void printCoordinates(); +}; + +class PolarPoint2D : public Point2D { +public: + PolarPoint2D() : Point2D() {} + PolarPoint2D(int a, int b) : Point2D(a, b) {} + void printCoordinates(); +}; \ No newline at end of file diff --git a/templates/_folder_Lectures/Lecture 15/parallell_2_OOP/Point2DVirtual.cpp b/templates/_folder_Lectures/Lecture 15/parallell_2_OOP/Point2DVirtual.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1672e7a1e11bcb071b302bbf823c3508dc3e431c --- /dev/null +++ b/templates/_folder_Lectures/Lecture 15/parallell_2_OOP/Point2DVirtual.cpp @@ -0,0 +1,14 @@ +#include <iostream> +#include "Point2DVirtual.h" + +void Point2DVirtual::printCoordinates() { + std::cout << "Virtualisation Base two coordinates: " << "(" << coord1 << ", " << coord2 << ")" << std::endl; +} + +void CartesianPoint2DVirtual::printCoordinates() { + std::cout << "Virtualisation Cartesian coordinates: " << "(x=" << coord1 << ", y=" << coord2 << ")" << std::endl; +} + +void PolarPoint2DVirtual::printCoordinates() { + std::cout << "Virtualisation Polar coordinates: " << "(radius=" << coord1 << ", angle=" << coord2 << ")" << std::endl; +} diff --git a/templates/_folder_Lectures/Lecture 15/parallell_2_OOP/Point2DVirtual.h b/templates/_folder_Lectures/Lecture 15/parallell_2_OOP/Point2DVirtual.h new file mode 100644 index 0000000000000000000000000000000000000000..57edf69f0dbe42ac6edd6480253bd494d01267c6 --- /dev/null +++ b/templates/_folder_Lectures/Lecture 15/parallell_2_OOP/Point2DVirtual.h @@ -0,0 +1,35 @@ +#pragma once + +class Point2DVirtual { +protected: + int coord1 = 0; + int coord2 = 0; +public: + Point2DVirtual(int a, int b) : coord1{a}, coord2{b} {} + Point2DVirtual() : coord1{0}, coord2{0} {} + virtual void printCoordinates(); + // virtual void printCoordinates() = 0; // If we declare a function as pure virtual, + // class Point2DVirtual would become + // an abstract class and it would be impossible + // to instantiate it - to have objects of that type. + // Uncomment the line with pure virtual function and + // comment the line above it. + // Can you run the program now? + // How would you overcome this and still have a vector + // of points using virtualisation to print each their + // own version of printCoordinates() function? +}; + +class CartesianPoint2DVirtual : public Point2DVirtual { +public: + CartesianPoint2DVirtual() : Point2DVirtual() {} + CartesianPoint2DVirtual(int a, int b) : Point2DVirtual(a, b) {} + void printCoordinates(); +}; + +class PolarPoint2DVirtual : public Point2DVirtual { +public: + PolarPoint2DVirtual() : Point2DVirtual() {} + PolarPoint2DVirtual(int a, int b) : Point2DVirtual(a, b) {} + void printCoordinates(); +}; \ No newline at end of file diff --git a/templates/_folder_Lectures/Lecture 15/parallell_2_OOP/main.cpp b/templates/_folder_Lectures/Lecture 15/parallell_2_OOP/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..382f66167765cb362ed0f57f7ab4f723d8dcb59d --- /dev/null +++ b/templates/_folder_Lectures/Lecture 15/parallell_2_OOP/main.cpp @@ -0,0 +1,50 @@ +#include <iostream> +#include <vector> +#include "Point2D.h" +#include "Point2DVirtual.h" + +int main() { + Point2D point{2, 3}; + CartesianPoint2D pointC{10, 20}; + PolarPoint2D pointP{1, 3}; + + // Example of polymorphism + // Derived classes call their version of the function printCoordinates() + // - they override base class' version of the same function + point.printCoordinates(); + pointC.printCoordinates(); + pointP.printCoordinates(); + + // Example of runtime polymorphism - virtualisation + // Base class Point2DVirtual has function printCoordinates() + // defined as virtual. + std::vector<Point2DVirtual*> points; + + points.reserve(12); + + for (int i = 0; i < 12; i++) { + if (i % 4 == 0) { + points.push_back(new Point2DVirtual); + } else if (i % 3 == 0) { + points.push_back(new CartesianPoint2DVirtual); + } else { + points.push_back(new PolarPoint2DVirtual); + } + } + + for (int i = 0; i < 12; i++) { + // virtualisation method invoked when the functions are called + // via pointer to the base class + points.at(i)->printCoordinates(); // In this line points.at(i) is of type + // "pointer to an instance (object) of class Point2dVirtual". + // We use operator "->" to get the member function + // printCoordinates() via pointer. + } + // and remember to deallocate elements of vector points: + for (int i = 0; i < 12; i++) { + delete points.at(i); + } + return 0; +} + +//------------------------------------------------------------------------------ diff --git a/templates/_folder_Lectures/Lecture 15/parallell_2_Pointers/main.cpp b/templates/_folder_Lectures/Lecture 15/parallell_2_Pointers/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..607e615179cd148113e319ae47128dc6ee94afc1 --- /dev/null +++ b/templates/_folder_Lectures/Lecture 15/parallell_2_Pointers/main.cpp @@ -0,0 +1,76 @@ +#include "std_lib_facilities.h" + +constexpr int NO_ERROR = 0; // we can have many error codes defined at some place + // in the program to be used as return values of functions + // to inform the caller about the state of the function +int incrementValues(int n, int* a, int* b); + +int main() { + // examples of pointer declarations + int a{0}; // variable a of type 'int' initialised to value 0 + int* ptrInt; // variable ptrInt of type 'pointer to integer', not initialised + + cout << "Variable a initial value: " << a << endl; + ptrInt = &a; // example of operator '&' - 'address of' + // variable ptrInt now contains the address of integer variable a + *ptrInt = 10; // example of use of operator '&' - 'content of' / pointer dereferencing + // the value stored in variable a is now changed + cout << "Variable a current value: " << a << endl; + + // example of using pointers for receiving more than one return value + // from a function + int firstNum{10}; + int secondNum{100}; + int returnStatus; + cout << "Initial values, before calling incrementValues:" << endl + << "firstNum: " << firstNum << " secondNum: " << secondNum << endl; + returnStatus = incrementValues(5, &firstNum, &secondNum); + cout << "After calling incrementValues:" << endl + << "firstNum: " << firstNum << " secondNum: " << secondNum << endl; + if (returnStatus == NO_ERROR) { // example how we can use return value of the function + // to pass info on error or exception (much C-like style) + cout << "incrementValues run with no errors." << endl; + } + + // example of dynamical allocation of matrix elements (Assignment 8) + const int matrixSize{3}; + int** matrix; + matrix = new int*[matrixSize]; // Variable matrix is a dynamically allocated array of + // matrixSize pointers to pointers to integer variables + for (int i = 0; i < matrixSize; i++) { + matrix[i] = new int[matrixSize]; // Each element of dynamically allocated matrix + // is assigned a value of a pointer to a dynamically + // allocated array of matrixSize integers + // *(matrix + i) = new int[matrixSize]; // equivalent to: matrix[i] = new int[matrixSize]; + } + for (int i = 0; i < matrixSize; i++) { + for (int j = 0; j < matrixSize; j++) { + matrix[i][j] = i+j; + } + } + // write the values of the matrix and check if they are correct (row+column) + for (int i = 0; i < matrixSize; i++) { + for (int j = 0; j < matrixSize; j++) { + cout << "m[" << i << "][" << j << "] = " << matrix[i][j] << " "; + } + cout << endl; + } + + // remember to deallocate memory with operator delete[] + // for each allocation with new[], there has to be a corresponding delete[] + for (int i = 0; i < matrixSize; i++) { + delete[] matrix[i]; + } + delete[] matrix; + + return 0; +} + +int incrementValues(int n, int* a, int* b) { + for (int i = 0; i < n; i++) { + (*a)++; + (*b)++; + } + + return NO_ERROR; +} \ No newline at end of file diff --git a/templates/_folder_Lectures/Lecture 15/parallell_2_Streams/Game.txt b/templates/_folder_Lectures/Lecture 15/parallell_2_Streams/Game.txt new file mode 100644 index 0000000000000000000000000000000000000000..0ea13ddd5eb67e23ba523c607b545a31a34cfee1 --- /dev/null +++ b/templates/_folder_Lectures/Lecture 15/parallell_2_Streams/Game.txt @@ -0,0 +1 @@ +100 Mitsuko diff --git a/templates/_folder_Lectures/Lecture 15/parallell_2_Streams/StartPosition.txt b/templates/_folder_Lectures/Lecture 15/parallell_2_Streams/StartPosition.txt new file mode 100644 index 0000000000000000000000000000000000000000..6534e8b8ee267de76116c5b61e637bf263d069f6 --- /dev/null +++ b/templates/_folder_Lectures/Lecture 15/parallell_2_Streams/StartPosition.txt @@ -0,0 +1 @@ +(5, 10) diff --git a/templates/_folder_Lectures/Lecture 15/parallell_2_Streams/main.cpp b/templates/_folder_Lectures/Lecture 15/parallell_2_Streams/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4e5b974c1cdc1dff3b8ee80e032fe5ad2d583f4b --- /dev/null +++ b/templates/_folder_Lectures/Lecture 15/parallell_2_Streams/main.cpp @@ -0,0 +1,46 @@ +#include <iostream> +#include <fstream> +#include <filesystem> + +constexpr std::string config = "Game.txt"; + +class Point2D { + int x; + int y; +public: + Point2D() : x{0}, y{0} {} + Point2D(int a, int b) : x{a}, y{b} {} + friend std::ostream& operator<<(std::ostream& outstream, const Point2D& pt); +}; + +std::ostream& operator<<(std::ostream& outstream, const Point2D& pt) { + outstream << "(" << pt.x << ", " << pt.y << ")" << std::endl; + return outstream; +} + +int main() { + std::filesystem::path fileName{"Game.txt"}; + std::ifstream inStream{fileName}; + int readScore; + std::string readPlayerName{""}; + + if (inStream.is_open()) { + inStream >> readScore >> readPlayerName; + } + std::cout << "Read points: " << readScore << std::endl + << "Read Player Name: " << readPlayerName << std::endl; + + // We can also use function getline() from the standard library + // to read the whole line from the file: + //std::string line{""}; + //std::getline(inStream, line); + //std::cout << "Read the line: " << line << std::endl; + + // example of calling operator << for a variable of a class type + // (see the class and function definitions at the top of this file) + Point2D startPos{5, 10}; + std::ofstream outStreamStart{"StartPosition.txt"}; + outStreamStart << startPos; + + return 0; +} \ No newline at end of file diff --git a/templates/_folder_Lectures/Lecture 15/parallell_2_Templates/main.cpp b/templates/_folder_Lectures/Lecture 15/parallell_2_Templates/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7c29d3c4fd404cb99efac228901bb8587a44b3e7 --- /dev/null +++ b/templates/_folder_Lectures/Lecture 15/parallell_2_Templates/main.cpp @@ -0,0 +1,87 @@ +#include <iostream> +#include <stack> +#include <queue> + +template<typename T> +class Qubit { + T x; + T y; + T z; +public: + Qubit(T a, T b, T c) : x{a}, y{b}, z{c} {} + void PrintQubit() { + std::cout << "This Qubit:" << std::endl + << "X: " << x << std::endl + << "Yi: " << y << std::endl + << "Z: " << z << std::endl; + } +}; + +template<typename T> +void Print3Times(T& val) { + std::cout << "Printing " << val << " " << "3 times:" << std::endl; + for (int i = 0; i < 3; i++) { + std::cout << val << " "; + } + std::cout << std::endl; +} + +template<typename T, int N> +void PrintNTimes(T& val) { + std::cout << "Printing " << val << " " << N << " times:" << std::endl; + for (int i = 0; i < N; i++) { + std::cout << val << " "; + } + std::cout << std::endl; +} + +class Point2D { + int x; + int y; +public: + Point2D() : x{0}, y{0} {} + Point2D(int a, int b) : x{a}, y{b} {} + friend std::ostream& operator<<(std::ostream& outstream, const Point2D& pt); +}; + +std::ostream& operator<<(std::ostream& outstream, const Point2D& pt) { + outstream << "(" << pt.x << ", " << pt.y << ")" << std::endl; + return outstream; +} + +int main() { + Qubit<int> qubit1{0, 0, 1}; + Qubit<double> qubit2{0.7, 0.7, 0.7}; + + qubit1.PrintQubit(); + qubit2.PrintQubit(); + + int num1{10}; + int num2{5}; + Print3Times(num1); // example of template argument deduction + PrintNTimes<int, 3>(num2); + Point2D point{2, 3}; + PrintNTimes<Point2D, 2>(point); // we need to have operator<<() overloaded for Point2D! + + // STL data structures + // The most used container / data structure from STL library is by far vector<>. + // We have already seen many examples of its use so here comes an example with + // stack and queue data structures. Stack is a LIFO (Last In First Out) and queue + // a FIFO (First In First Out) data structure. This is reflected in how method pop() + // removes elements from each of them as illustrated in the example below: + // You don't have to know all of the data structures from STL! stack and queue are + // given just as examples. + std::stack<int> stack1; + std::queue<int> queue1; + + for (int i = 0; i < 10; i++) { + stack1.push(i); + queue1.push(100*i); + } + while (!(stack1.empty() || queue1.empty())) { + std::cout << stack1.top() << std::endl; + std::cout << queue1.front() << std::endl; + stack1.pop(); + queue1.pop(); + } +} \ No newline at end of file