diff --git a/seminar01_overload/homework/code/01_myspace/myspace.cpp b/seminar01_overload/01_myspace/myspace.cpp similarity index 100% rename from seminar01_overload/homework/code/01_myspace/myspace.cpp rename to seminar01_overload/01_myspace/myspace.cpp diff --git a/seminar01_overload/homework/code/02_cubev/cubev.cpp b/seminar01_overload/02_cubev/cubev.cpp similarity index 100% rename from seminar01_overload/homework/code/02_cubev/cubev.cpp rename to seminar01_overload/02_cubev/cubev.cpp diff --git a/seminar01_overload/homework/code/03_cuber/cuber.cpp b/seminar01_overload/03_cuber/cuber.cpp similarity index 100% rename from seminar01_overload/homework/code/03_cuber/cuber.cpp rename to seminar01_overload/03_cuber/cuber.cpp diff --git a/seminar01_overload/homework/code/04_count_letters/count_letters.cpp b/seminar01_overload/04_count_letters/count_letters.cpp similarity index 100% rename from seminar01_overload/homework/code/04_count_letters/count_letters.cpp rename to seminar01_overload/04_count_letters/count_letters.cpp diff --git a/seminar01_overload/homework/code/05_add_price/add_price.cpp b/seminar01_overload/05_add_price/add_price.cpp similarity index 100% rename from seminar01_overload/homework/code/05_add_price/add_price.cpp rename to seminar01_overload/05_add_price/add_price.cpp diff --git a/seminar01_overload/homework/code/06_is_expensive/is_expensive.cpp b/seminar01_overload/06_is_expensive/is_expensive.cpp similarity index 100% rename from seminar01_overload/homework/code/06_is_expensive/is_expensive.cpp rename to seminar01_overload/06_is_expensive/is_expensive.cpp diff --git a/seminar01_overload/homework/code/07_vector3f/main.cpp b/seminar01_overload/07_vector3f/main.cpp similarity index 100% rename from seminar01_overload/homework/code/07_vector3f/main.cpp rename to seminar01_overload/07_vector3f/main.cpp diff --git a/seminar01_overload/homework/code/07_vector3f/vector3f.h b/seminar01_overload/07_vector3f/vector3f.h similarity index 100% rename from seminar01_overload/homework/code/07_vector3f/vector3f.h rename to seminar01_overload/07_vector3f/vector3f.h diff --git a/seminar01_overload/homework/code/08_complex/complex.h b/seminar01_overload/08_complex/complex.h similarity index 100% rename from seminar01_overload/homework/code/08_complex/complex.h rename to seminar01_overload/08_complex/complex.h diff --git a/seminar01_overload/homework/code/08_complex/complex_image.cpp b/seminar01_overload/08_complex/complex_image.cpp similarity index 100% rename from seminar01_overload/homework/code/08_complex/complex_image.cpp rename to seminar01_overload/08_complex/complex_image.cpp diff --git a/seminar01_overload/homework/code/08_complex/complex_movie.cpp b/seminar01_overload/08_complex/complex_movie.cpp similarity index 100% rename from seminar01_overload/homework/code/08_complex/complex_movie.cpp rename to seminar01_overload/08_complex/complex_movie.cpp diff --git a/seminar01_overload/homework/code/08_complex/complex_movie.mp4 b/seminar01_overload/08_complex/complex_movie.mp4 similarity index 100% rename from seminar01_overload/homework/code/08_complex/complex_movie.mp4 rename to seminar01_overload/08_complex/complex_movie.mp4 diff --git a/seminar01_overload/homework/code/08_complex/complex_test.cpp b/seminar01_overload/08_complex/complex_test.cpp similarity index 100% rename from seminar01_overload/homework/code/08_complex/complex_test.cpp rename to seminar01_overload/08_complex/complex_test.cpp diff --git a/seminar01_overload/homework/code/08_complex/julia.cpp b/seminar01_overload/08_complex/julia.cpp similarity index 100% rename from seminar01_overload/homework/code/08_complex/julia.cpp rename to seminar01_overload/08_complex/julia.cpp diff --git a/seminar01_overload/homework/code/08_complex/julia_images/-0.4+0.6i.ppm b/seminar01_overload/08_complex/julia_images/-0.4+0.6i.ppm similarity index 100% rename from seminar01_overload/homework/code/08_complex/julia_images/-0.4+0.6i.ppm rename to seminar01_overload/08_complex/julia_images/-0.4+0.6i.ppm diff --git a/seminar01_overload/homework/code/08_complex/julia_images/-0.7-0.38i.ppm b/seminar01_overload/08_complex/julia_images/-0.7-0.38i.ppm similarity index 100% rename from seminar01_overload/homework/code/08_complex/julia_images/-0.7-0.38i.ppm rename to seminar01_overload/08_complex/julia_images/-0.7-0.38i.ppm diff --git a/seminar01_overload/homework/code/08_complex/julia_images/-0.8+0.16i.ppm b/seminar01_overload/08_complex/julia_images/-0.8+0.16i.ppm similarity index 100% rename from seminar01_overload/homework/code/08_complex/julia_images/-0.8+0.16i.ppm rename to seminar01_overload/08_complex/julia_images/-0.8+0.16i.ppm diff --git a/seminar01_overload/homework/code/08_complex/julia_images/0.28+0.011i.ppm b/seminar01_overload/08_complex/julia_images/0.28+0.011i.ppm similarity index 100% rename from seminar01_overload/homework/code/08_complex/julia_images/0.28+0.011i.ppm rename to seminar01_overload/08_complex/julia_images/0.28+0.011i.ppm diff --git a/seminar01_overload/homework/code/08_complex/julia_movie.cpp b/seminar01_overload/08_complex/julia_movie.cpp similarity index 100% rename from seminar01_overload/homework/code/08_complex/julia_movie.cpp rename to seminar01_overload/08_complex/julia_movie.cpp diff --git a/seminar01_overload/homework/code/08_complex/mandelbrot.cpp b/seminar01_overload/08_complex/mandelbrot.cpp similarity index 100% rename from seminar01_overload/homework/code/08_complex/mandelbrot.cpp rename to seminar01_overload/08_complex/mandelbrot.cpp diff --git a/seminar01_overload/homework/code/08_complex/mandelbrot_images/mandelbrot.ppm b/seminar01_overload/08_complex/mandelbrot_images/mandelbrot.ppm similarity index 100% rename from seminar01_overload/homework/code/08_complex/mandelbrot_images/mandelbrot.ppm rename to seminar01_overload/08_complex/mandelbrot_images/mandelbrot.ppm diff --git a/seminar01_overload/classroom_tasks/classroom_tasks_overload.pdf b/seminar01_overload/classroom_tasks/classroom_tasks_overload.pdf deleted file mode 100644 index 3cfca38..0000000 Binary files a/seminar01_overload/classroom_tasks/classroom_tasks_overload.pdf and /dev/null differ diff --git a/seminar01_overload/classroom_tasks/classroom_tasks_overload.tex b/seminar01_overload/classroom_tasks/classroom_tasks_overload.tex deleted file mode 100644 index 2bb1e48..0000000 --- a/seminar01_overload/classroom_tasks/classroom_tasks_overload.tex +++ /dev/null @@ -1,180 +0,0 @@ -\documentclass{article} -\usepackage[utf8x]{inputenc} -\usepackage{ucs} -\usepackage{amsmath} -\usepackage{amsfonts} -\usepackage{marvosym} -\usepackage{wasysym} -\usepackage{upgreek} -\usepackage[english,russian]{babel} -\usepackage{graphicx} -\usepackage{float} -\usepackage{textcomp} -\usepackage{hyperref} -\usepackage{geometry} - \geometry{left=2cm} - \geometry{right=1.5cm} - \geometry{top=1cm} - \geometry{bottom=2cm} -\usepackage{tikz} -\usepackage{ccaption} -\usepackage{multicol} -\usepackage{fancyvrb} - -\usepackage{listings} -%\setlength{\columnsep}{1.5cm} -%\setlength{\columnseprule}{0.2pt} - -\usepackage{colortbl,graphicx,tikz} -\definecolor{X}{rgb}{.5,.5,.5} - -\title{ДЗ. Работа с изображениями в формате \texttt{.ppm}} -\date{} -\begin{document} -\pagenumbering{gobble} - -\lstset{ - language=C++, % choose the language of the code - basicstyle=\linespread{1.1}\ttfamily, - columns=fixed, - fontadjust=true, - basewidth=0.5em, - keywordstyle=\color{blue}\bfseries, - commentstyle=\color{gray}, - stringstyle=\ttfamily\color{orange!50!black}, - showstringspaces=false, - %numbers=false, % where to put the line-numbers - numbersep=5pt, - numberstyle=\tiny\color{black}, - numberfirstline=true, - stepnumber=1, % the step between two line-numbers. - numbersep=10pt, % how far the line-numbers are from the code - backgroundcolor=\color{white}, % choose the background color. You must add \usepackage{color} - showstringspaces=false, % underline spaces within strings - captionpos=b, % sets the caption-position to bottom - breaklines=true, % sets automatic line breaking - breakatwhitespace=true, % sets if automatic breaks should only happen at whitespace - xleftmargin=.2in, - extendedchars=\true, - keepspaces = true, -} -\lstset{literate=% - *{0}{{{\color{red!20!violet}0}}}1 - {1}{{{\color{red!20!violet}1}}}1 - {2}{{{\color{red!20!violet}2}}}1 - {3}{{{\color{red!20!violet}3}}}1 - {4}{{{\color{red!20!violet}4}}}1 - {5}{{{\color{red!20!violet}5}}}1 - {6}{{{\color{red!20!violet}6}}}1 - {7}{{{\color{red!20!violet}7}}}1 - {8}{{{\color{red!20!violet}8}}}1 - {9}{{{\color{red!20!violet}9}}}1 -} - -\title{Семинар \#1: Введение в язык C++ (для тех, кто знает C). Классные задачи.\vspace{-5ex}}\date{}\maketitle - -\section*{Hello world++} -Пишем первую программу на \texttt{C++} -\begin{lstlisting} -#include -int main() { - printf("Hello World++\n"); -} -\end{lstlisting} -Все библиотеки из языка \texttt{C} можно использовать и в языке \texttt{C++}. Только название библиотеки без \texttt{.h} на конце и с символом \texttt{c} в начале: -\begin{verbatim} - -------> -\end{verbatim} - -Для компиляции используйте компилятор \texttt{g++}. Вот так: -\begin{verbatim} -g++ helloworld.cpp -./a.out -\end{verbatim} -Или, если вы хотите установить у исполняемого файла своё имя за место \texttt{a.out}: -\begin{verbatim} -g++ -o hello helloworld.cpp -./hello -\end{verbatim} - -\begin{itemize} -\item \textbf{Задача 1:} Скомпилируйте и запустите простейшую программу \texttt{00helloworld.cpp}. -\item \textbf{Задача 2:} Разберитесь в программе \texttt{01structnaming.cpp}. Скомпилируйте и запустите. -\end{itemize} - -\section*{Тип bool} -В прошлом семестре, для хранения результатов логических операций, мы использовали целочисленные типы.\\ -В языке \texttt{C++} есть встроенный тип \texttt{bool}, который может принимать 2 значения (\texttt{true} и \texttt{false}). -\begin{lstlisting} -#include -int main() { - bool a = true; - bool b = false; - bool c = a || b; - - if (c) - printf("Yes\n"); - else - printf("No\n"); -} -\end{lstlisting} -\begin{itemize} -\item \textbf{Задача 3:} Что напечатает эта программа? Скомпилируйте её и запустите (\texttt{02bool.cpp}) -\item \textbf{Задача 4:} Напишите функцию, которая будет принимать на вход целое число и возвращать \texttt{true}, если число оканчивается на \texttt{0} и \texttt{false} иначе. Вызовите эту функцию из \texttt{main}. -\end{itemize} - -\newpage -\section*{Пространство имён} -\begin{lstlisting} -#include -// Определяем переменные, структуры, функции внутри пространства имён foo -namespace foo { - int a = 5; - int square(int x) { - return x * x; - } -} -// Чтобы получить доступ к ним вне пространства имён, нужно добавить к именам foo:: -int main() { - printf("%d\n", foo::a); -} -\end{lstlisting} -\begin{itemize} -\item \textbf{Задача 5:} Возведите \texttt{foo::a} в квадрат с помощью функции \texttt{foo::square}. -\item \textbf{Задача 6:} Создайте своё пространство имён по имени \texttt{bar} и определите в нём переменную \texttt{a = 7}. Напечатайте значение этой переменной в \texttt{main}. -\item \textbf{Задача 7:} Сделайте задание в программе \texttt{03namespace.cpp}. -\end{itemize} - -\section*{Ссылки} -Ссылка -- это переменная, которая является новым именем для существующего участка памяти. -\begin{lstlisting} -#include - -int main() { - int a = 10; - // Создадим ссылку r на переменную a - int& r = a; - // Теперь, если изменить r, то поменяется и a - r += 5; - printf("%d\n", a); -} -\end{lstlisting} -Ссылки часто используются для тех же целей, что и указатели (только со ссылкам работать удобнее). -В отличии от указателей, ссылки: -\begin{enumerate} -\item Должны всегда инициализироваться при создании -\item Не могут никуда не ссылаться (т.е. не могут равняться \texttt{NULL}) -\item Их нельзя переприсвоить. При использовании оператора \texttt{=} со ссылками изменяется та переменная, на которую ссылка ссылается, а не сама ссылка. -\end{enumerate} -\begin{itemize} -\item \textbf{Задача 8:} Сделайте задание в файлах \texttt{04ref.cpp}, \texttt{05ref.cpp} и \texttt{06ref.cpp}. -\end{itemize} -\section*{Перегрузка функций} -\begin{itemize} -\item \textbf{Задача 9:} Сделайте задание в файлах \texttt{07function\_overload.cpp}, \texttt{08nulptr.cpp} и \texttt{09default\_arguments.cpp}. -\end{itemize} -\section*{Перегрузка операторов} -\begin{itemize} -\item \textbf{Задача 10:} Сделайте задание в файлах \texttt{10operator\_overload.cpp}, \texttt{11iostream.cpp} и \texttt{12iostream\_overload.cpp}. -\end{itemize} -\end{document} \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/00namespace/00hello.cpp b/seminar01_overload/classroom_tasks/code/00namespace/00hello.cpp deleted file mode 100644 index eef258d..0000000 --- a/seminar01_overload/classroom_tasks/code/00namespace/00hello.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include - -/* - Здравствуйте, это первый файл семестра по языку C++ (для тех, кто знаком с языком C) - - Язык C++ создан на основе языка C и одним из приоритетов C++ является обратная совместимость с C - Поэтому почти любая программа на языке C будет работать и на языке C++ - - Однако, нужно помнить, что это разные языки. В C++ было добавлено огромное количество новых возможностей, - что сделало C++ возможно самым объёмным и мощным языком программирования. - - C++ содержит в себе во много раз больше всего, чем язык C и пройти его за один семестр не представляется возможным, - но мы пройдём ключевые части этого языка. - - - Для компиляции программ на C++ будем использовать компилятор g++. - Скомпилируйте эту программу вот так: - g++ 00hello.cpp - - И запустите вот так (для Windows): - a.exe - - И запустите вот так (для Linux): - ./a.out - -*/ - - -int main() -{ - printf("Hello World of C++\n"); -} - diff --git a/seminar01_overload/classroom_tasks/code/00namespace/01namespace.cpp b/seminar01_overload/classroom_tasks/code/00namespace/01namespace.cpp deleted file mode 100644 index 7b6c2b6..0000000 --- a/seminar01_overload/classroom_tasks/code/00namespace/01namespace.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include - -/* - Пространства имён - namespace - - Определяем переменные/структуры/функции внутри пространства имён. - Давайте назовём его mipt - - Чтобы получить доступ к этим переменным/структурам/функциям - вне пространства имён, нужно добавить к имени название пространства имён и оператор :: - В данном случае нужно добавить mipt:: -*/ - - -namespace mipt -{ - int a = 5; - float b = 1.2; - - int square(int x) - { - return x * x; - } -} - - -int main() -{ - printf("%i\n", mipt::square(4)); -} - - -/* - Задание: - - 1) Скомпилируйте программу и запустите, что она напечатает? - - 2) Что будет, если забыть написать mipt:: у названия функции square? - - 3) Передайте в функцию mipt::square переменную a из пространства имён mipt - - 4) Напишите функцию float average(float x, float y), которая будет принимать 2 числа - и возвращать их среднее арифметическое. - Поместите эту функцию в пространство имён mipt и вызовите эту функцию из main - - 5) Напечатайте среднее арифметическое от a и b, используя функцию average - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/00namespace/01namespace_solution.cpp b/seminar01_overload/classroom_tasks/code/00namespace/01namespace_solution.cpp deleted file mode 100644 index b6d9059..0000000 --- a/seminar01_overload/classroom_tasks/code/00namespace/01namespace_solution.cpp +++ /dev/null @@ -1,25 +0,0 @@ -#include - - -namespace mipt -{ - int a = 5; - float b = 1.2; - - int square(int x) - { - return x * x; - } - - float average(float x, float y) - { - return (x + y) / 2; - } -} - - -int main() -{ - printf("%i\n", mipt::square(mipt::a)); - printf("%f\n", mipt::average(mipt::a, mipt::b)); -} diff --git a/seminar01_overload/classroom_tasks/code/00namespace/02struct_type_name.cpp b/seminar01_overload/classroom_tasks/code/00namespace/02struct_type_name.cpp deleted file mode 100644 index f965277..0000000 --- a/seminar01_overload/classroom_tasks/code/00namespace/02struct_type_name.cpp +++ /dev/null @@ -1,24 +0,0 @@ -#include - -/* - В языке C при объявлении структуры struct Book создаётся тип по имени struct Book. - - В языке C++ при объявлении структуры struct Book создаётся тип к которому - можно обращаться как по имени struct Book так и по имени Book -*/ - - -struct Book -{ - char title[50]; - int pages; - float price; -}; - - -int main() -{ - struct Book a = {"Tom Sawyer", 280, 500}; - - Book b = {"War and Peace", 1200, 900}; -} diff --git a/seminar01_overload/classroom_tasks/code/00namespace/03namespace.cpp b/seminar01_overload/classroom_tasks/code/00namespace/03namespace.cpp deleted file mode 100644 index 4ece511..0000000 --- a/seminar01_overload/classroom_tasks/code/00namespace/03namespace.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include - -/* - Определяем переменные/структуры/функции внутри пространства имён mipt - Затем к ним можно будет доступиться используя префикс mipt:: -*/ - - -namespace mipt -{ - struct Book - { - char title[50]; - int pages; - float price; - }; - - void printBook(Book b) - { - printf("%s, pages: %d, price: %.2f\n", b.title, b.pages, b.price); - } -} - - - -int main() -{ - -} - -/* - Задание: - - Структура Book и функция printBook определены в пространстве имён mipt - - 1) Создайте переменную типа структура Book и иницилизируйте - её значениями: "War and Peace", 1200, 900 - - 2) Напечатайте созданную переменную с помощью функции printBook -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/00namespace/03namespace_solution.cpp b/seminar01_overload/classroom_tasks/code/00namespace/03namespace_solution.cpp deleted file mode 100644 index 7c0d26f..0000000 --- a/seminar01_overload/classroom_tasks/code/00namespace/03namespace_solution.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include - - -namespace mipt -{ - struct Book - { - char title[50]; - int pages; - float price; - }; - - void printBook(Book b) - { - printf("%s, pages: %d, price: %.2f\n", b.title, b.pages, b.price); - } -} - - - -int main() -{ - mipt::Book b = {"War and Peace", 1200, 900}; - mipt::printBook(b); -} - -/* - Задание: - - Структура Book и функция printBook определены в пространстве имён mipt - - 1) Создайте переменную типа структура Book и иницилизируйте - её значениями: "War and Peace", 1200, 900 - - 2) Напечатайте созданную переменную с помощью функции printBook -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/00namespace/04name_collision.cpp b/seminar01_overload/classroom_tasks/code/00namespace/04name_collision.cpp deleted file mode 100644 index e65a429..0000000 --- a/seminar01_overload/classroom_tasks/code/00namespace/04name_collision.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include - -/* - Зачем вообще нужны пространства имён? - - Представьте, что вы создаёте большую программу, исходный код который - содержит миллионы строк кода. Конечно, большая часть кода написана не вами, - так как вы используете библиотеки, написанные другими программистами. - - Библиотекой можно назвать совокупность файлов исходного кода, нацеленных - на решение какой-либо задачи. Например, есть библиотека для работы с графикой - в которой содержатся функции/структуры/классы для работы с графикой. - - Если вы подключаете несколько библиотек, то существует высокая вероятность, - что название чего-либо из одной библиотеки совпадёт с названием чего-то из другой библиотеки. - Это, конечно, приведёт к ошибке. - - Чтобы этого избежать и используются пространства имён. -*/ - - - -namespace audio -{ - int a = 10; - - int calculate(int x) - { - return x + 1; - } -} - - -namespace graphics -{ - int a = 20; - - int calculate(int x) - { - return x * 2; - } -} - - - -int main() -{ - printf("%i\n", audio::a); - printf("%i\n", graphics::a); - - - printf("%i\n", graphics::calculate(audio::calculate(graphics::a))); -} - - -/* - Задание: - - 1) Что напечатает данная программа? -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/00namespace/05using.cpp b/seminar01_overload/classroom_tasks/code/00namespace/05using.cpp deleted file mode 100644 index d3833db..0000000 --- a/seminar01_overload/classroom_tasks/code/00namespace/05using.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include - -/* - Если вам очень не хочется постоянно писать названия пространства имён, - то вы можете использовать ключевое слово using - - using namespace audio; - - Это говорит о том, что начиная с этой строки audio:: перед именами писать больше не нужно - - Это, конечно, полностью уничтожают всю пользу, которую приносят пространства имён. - То есть в больших проектах могут возникнуть ошибки, связанные с одинаковыми именами. - - Так что так лучше не делать, а если и делать, то только в маленьких программах. -*/ - - -namespace audio -{ - int a = 10; - - int calculate(int x) - { - return x + 1; - } -} - - -namespace graphics -{ - int a = 20; - - int calculate(int x) - { - return x * 2; - } -} - -namespace network -{ - int b = 20; - - int solve(int x) - { - return x * 2; - } -} - -using namespace audio; - -int main() -{ - printf("%i\n", calculate(a)); -} - - -/* - Задание: - - 1) Что напечатает данная программа? - - 2) Если заменить using namespace audio на using namespace graphics, то что напечатает программа? - - 3) Что если одновременно использовать пространство имён audio и пространство имён graphics? - - using namespace audio; - using namespace graphics; - - Приведёт ли это к ошибке и, если да, то почему? - - - 4) Что если одновременно использовать пространство имён audio и пространство имён network? - - using namespace audio; - using namespace network; - - Приведёт ли это к ошибке и, если да, то почему? -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/00namespace/06std_cout.cpp b/seminar01_overload/classroom_tasks/code/00namespace/06std_cout.cpp deleted file mode 100644 index 436f140..0000000 --- a/seminar01_overload/classroom_tasks/code/00namespace/06std_cout.cpp +++ /dev/null @@ -1,65 +0,0 @@ -#include - -/* - Все переменные/функции/структуры/классы стандартной библиотеки языка C++ содержатся в пространстве имён std - Рассмотрим, например, глобальную переменную cout, определённую в библиотеке iostream в пространстве имён std. - - К этой переменной можно применять оператор << - cout << объект - В результате этой операции объект напечатается на экран (если он может напечататься) - Результат оператора << также является cout, поэтому можно применять << несколько раз: - - - - Например это выражение: cout << "Hello " << "World" << "\n"; - - 1) Сначала напечатается "Hello " и на место cout << "Hello " подставится cout - Получтся cout << "World" << "\n"; - - 2) Потом напечатется "World" и на место cout << "World" подставится cout - Получтся cout << "\n"; - - 3) В конце напечатается перенос строки -*/ - - - -int main() -{ - std::cout << "Hello World\n"; - std::cout << 5 << "\n"; - - int x = 10; - std::cout << 5 << "\n"; -} - - -/* - Задачи: - - 1) Напечатайте на экран число 1.4, используя cout (количество печатаемых знаков после запятой неважно) - Обратите внимание, что при печати с cout не нужно указывать спецификатор типа как в printf. - cout сам понимает объект какого типа ему передаётся - - 2) Напечатайте фразу "I am x years old", только за место x нужно подставить значение - переменной x. В данной задаче получится "I am 10 years old". Используйте cout. - - 3) Напечатайте на экран числа от 1 до 20, разделённые пробелом. Используйте cout - - 4) Вместо \n для переноса строки можно использовать endl - специальный объект из - пространства имён std. - Если мы передаём его объекту cout через оператор << то печатается перенос строки - - Замените все переносы строк с \n на endl - std::cout << 5 << "\n"; --> std::cout << 5 << std::endl; - - - На самом деле std::endl работает медленней, чем \n, так как он помимо печати делает flush - Поэтому, если важна скорость печати в буфер, то лучше использовать \n - - - 5) Что будет если не написать std:: перед одним из cout? - - 6) Используйте using namespace std; и избавьтесь от надоедливых std:: перед cout и endl - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/00namespace/06std_cout_solution.cpp b/seminar01_overload/classroom_tasks/code/00namespace/06std_cout_solution.cpp deleted file mode 100644 index 744d55c..0000000 --- a/seminar01_overload/classroom_tasks/code/00namespace/06std_cout_solution.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include -using namespace std; - - -int main() -{ - cout << 1.4 << endl; - - int x = 10; - cout << "I am " << x << " years old" << endl; - - for (int i = 1; i <= 20; ++i) - cout << i << " "; - cout << endl; - -} diff --git a/seminar01_overload/classroom_tasks/code/00namespace/07std_using_one_name.cpp b/seminar01_overload/classroom_tasks/code/00namespace/07std_using_one_name.cpp deleted file mode 100644 index 5d1277c..0000000 --- a/seminar01_overload/classroom_tasks/code/00namespace/07std_using_one_name.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include - -/* - В пространстве имён std очень много разных имён. Если мы добавим их всех, используя - using namespace std; - то это может привести к проблеме. - Одно из имён из std может совпасть с названием нашего объекта и это может привести к ошибке. - - Так что лучше такую возможность не использовать. - - Но можно добавить только одно имя так: - using std::cout; - Начиная с этого момента можно писать просто cout. - Но для всех остальных объектов из std вы должны продолжать писать std:: -*/ - -using std::cout; - - -int main() -{ - cout << "Hello World" << std::endl; - cout << 5 << std::endl; -} - - -/* - Задачи: - - 1) Добавить endl в нашу область видимости, также как и cout - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/00namespace/08std_cin.cpp b/seminar01_overload/classroom_tasks/code/00namespace/08std_cin.cpp deleted file mode 100644 index 9547de5..0000000 --- a/seminar01_overload/classroom_tasks/code/00namespace/08std_cin.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include - -/* - Счтиывание из стандартного входа - - Рассмотрим глобальную переменную cin, определённую в библиотеке iostream в пространстве имён std. - - К этой переменной можно применять оператор >> - cin >> объект - В результате этой операции объект считается с экрана (если он может быть считан) - Результат оператора >> также является cin, поэтому можно применять >> несколько раз: - - - - Например это выражение: cin >> a >> b; - - 1) Сначала считается переменная a и на место cin >> a подставится cin - Получтся cin >> b; - - 2) Потом считается переменная b -*/ - - - -int main() -{ - int a, b; - std::cin >> a >> b; - std::cout << a + b; -} - - -/* - Задачи: - - 1) Что напечатает данная программа, если на вход передать числа 10 и 20? - - 2) Напишите программу, которая будет считывать два вещественных числа и печатать их среднее геометрическое - Функция корня sqrt есть в библиотеке - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/00namespace/08std_cin_solution.cpp b/seminar01_overload/classroom_tasks/code/00namespace/08std_cin_solution.cpp deleted file mode 100644 index 56b5d96..0000000 --- a/seminar01_overload/classroom_tasks/code/00namespace/08std_cin_solution.cpp +++ /dev/null @@ -1,10 +0,0 @@ -#include -#include - - -int main() -{ - float a, b; - std::cin >> a >> b; - std::cout << sqrt(a * b); -} diff --git a/seminar01_overload/classroom_tasks/code/00namespace/09cprog.cpp b/seminar01_overload/classroom_tasks/code/00namespace/09cprog.cpp deleted file mode 100644 index 23dcdee..0000000 --- a/seminar01_overload/classroom_tasks/code/00namespace/09cprog.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include -#include - -/* - Язык C++ обратно совместим с языком C. То есть почти любая программа на C будет работать на C++ - Эта программа будет работать. - - Обратите внимания, для имён, пришедших из языка C использовать std:: не обязательно - - Программа работает, несмотря на то, что мы используем библиотечные - функции printf и sqrt без указания пространства имён std. -*/ - - - -int main() -{ - printf("%f", sqrt(3)); -} - - -/* Задача: - - 1) Что напечатает данная программа? - - 2) Использование библиотечных функций без std опасно, так как может привести к ошибкам, - связанных с совпадением имён. Помните, что большая программа может иметь миллионы - строк кода и совпадение ваших имен и библиотечных имён очень вероятно. - - - Напишите следующую функцию перед функцией main - - int sqrt(int x) - { - return x + 1; - } - - Что теперь напечатает программа? Объясните результат. -*/ - - - diff --git a/seminar01_overload/classroom_tasks/code/00namespace/10cprog_with_std.cpp b/seminar01_overload/classroom_tasks/code/00namespace/10cprog_with_std.cpp deleted file mode 100644 index 675de5c..0000000 --- a/seminar01_overload/classroom_tasks/code/00namespace/10cprog_with_std.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include - -/* - Желательно всё равно использовать std даже для имён пришедших из языка C - - Также были изменены названия библиотек: - stdio.h --> cstdio - math.h --> cmath - cmath означает, что это библиотека языка C под названием math, поэтому и cmath - - Они почти не отличаются от предыдущих, но при программировании на C++ - желательно использовать именно эти библиотеки. -*/ - - -int main() -{ - std::printf("%f", std::sqrt(3)); -} - - -/* Задача: - - 1) Что напечатает данная программа? - - 2) Напишите следующую функцию перед функцией main - - int sqrt(int x) - { - return x + 1; - } - - Что теперь напечатает программа? Объясните результат. -*/ - - diff --git a/seminar01_overload/classroom_tasks/code/01ref/00ref.cpp b/seminar01_overload/classroom_tasks/code/01ref/00ref.cpp deleted file mode 100644 index e5ec010..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/00ref.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - В C++ вводится понятие нового типа под названием Ссылка - - Ссылку можно рассматривать как новое имя для объекта. - Ссылку также можно рассматривать как удобный указатель, который автоматически разыменовывается - (На самом деле под капотом ссылка и является указателем) - - Ссылка объявляется с помощью значка & после имени типа. - Не стоит путать & используемый при объявлении ссылки с & используемым для нахождения адреса переменной. - Это разные & - - - Пусть есть переменная a - int a = 10; - Давайте создадим указатель и ссылку на эту переменную и увеличим её на 1 с помощью указателя/ссылки - - Используем указатель: Используем ссылку: - int* p = &a; int& r = a; - *p += 1; r += 1; - - - Ссылкой пользоваться удобно, так как: - - 1) При создании ссылки нам не нужно передавать ей адрес - Просто передаём ей саму переменную, а ссылка уже сама находит её адрес - - 2) Не нужно её разыменовывать, она всегда разыменовывается сама - -*/ - -int main() -{ - int a = 10; - - int& r = a; - r += 1; - - cout << a << endl; -} - - -/* - Задачи: - - 1) Используйте ссылку r, чтобы увеличить a в 2 раза - Проверьте, как изменилась a, напечатав её - - - 2) Используйте ссылку r, чтобы присвоить a число 100 - Проверьте, как изменилась a, напечатав её - - - 3) Создайте переменную b типа float, равную 1.5 - Создайте ссылку на b и используйте эту ссылку, чтобы возвести b в квадрат - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/01ref.cpp b/seminar01_overload/classroom_tasks/code/01ref/01ref.cpp deleted file mode 100644 index d1af855..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/01ref.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Пусть у нас есть некоторый объект, например - int a = 10; - - После того как мы создали ссылку на этот объект - int& r = a; - - Все (почти) операции применяемые к ссылке r применяются на самом деле к объекту a - Как будто у одного объекта теперь два имени a и r - Поэтому можно сказать, что ссылка это новое имя для объекта - - При этом изменить саму ссылку (например, чтобы она начала указывать на другое имя) нельзя -*/ - -int main() -{ - int a = 10; - int& r = a; - - - r += 5; // Прибавим к a число 5 - r *= 2; // Умножим a на 2 - cout << r << endl; // Напечатаем a - cout << sizeof(r) << endl; // Напечатаем размер a - cout << &r << endl; // Напечатаем адрес a -} - - -/* - Задачи: - - 1) Чему будет равно значение a в конце этой программы - - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/02ref.cpp b/seminar01_overload/classroom_tasks/code/01ref/02ref.cpp deleted file mode 100644 index 106b64e..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/02ref.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Пусть у нас есть некоторый объект, например - int a = 10; - - После того как мы создали ссылку на этот объект - int& r = a; - - Все (почти) операции применяемые к ссылке r применяются на самом деле к объекту a - Как будто у одного объекта теперь два имени a и r - Поэтому можно сказать, что ссылка это новое имя для объекта - - При этом изменить саму ссылку (например, чтобы она начала указывать на другое имя) нельзя -*/ - -int main() -{ - int a[5] = {10, 20, 30, 40, 50}; - - int& b = a[1]; - b += 1; - - for (int i = 0; i < 5; ++i) - { - cout << a[i] << " "; - } - cout << endl; -} - - -/* - Задачи: - - 1) Что будет содержать массив a в конце данной программы? - - 2) Создайте ссылку, которая будет указывать на последний элемент массива a - Используйте эту ссылку, чтобы умножить последний элемент массива на 2 - Напечатайте этот массив - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/03ref_pointer_diff_init.cpp b/seminar01_overload/classroom_tasks/code/01ref/03ref_pointer_diff_init.cpp deleted file mode 100644 index b6142bb..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/03ref_pointer_diff_init.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Несмотря на то, что ссылки и указатели во многом похожи, у них есть и много больших отличий. - (помимо разной инициализации и того, что ссылку не нужно постоянно разыменовывать) - - - Различие 1) - Указатель можно создать без инициализации вот так: - int* p; - В этом случае в p будет храниться произвольный адрес. - Разыменовывать такой указатель, не задав его значение адресом какого-либо объекта, - очень опасно, это может привести к сложновыявляемым ошибкам. - - Ссылку нельзя создать без инициализации, то есть так нельзя: - int& r; - При создании ссылки нужно указать на что она будет указывать - - - Различие 2) - Указатель можно приравнять нулевому значению - В C++ вводится специальное нулевое значение для указателя nullptr - Вместо NULL, который был просто равен числу 0. В C++ лучше использовать nullptr - Разыменование нулевого указателя также приведёт к ошибке. - - Ссылку нельзя присвоить никакому нулевому значению - -*/ - -int main() -{ - -} - - -/* - Задачи: - - 1) Попробуйте создать: - a) Указатель без инициализации - б) Ссылку без инициализации - - в) Указатель, равнуй нулевому значению nullptr - г) Ссылку, равную нулю - - Скомпилируется ли программа в этих 4-х случаях? -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/04ref_pointer_diff_assign.cpp b/seminar01_overload/classroom_tasks/code/01ref/04ref_pointer_diff_assign.cpp deleted file mode 100644 index 46a707a..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/04ref_pointer_diff_assign.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Несмотря на то, что ссылки и указатели во многом похожи, у них есть и много больших отличий. - (помимо разной инициализации и того, что ссылку не нужно постоянно разыменовывать) - - - Различие 3) Указатель можно переприсвоить. Если указатель сначала указывал в одно место, - например, на переменную a, то можно просто написать - p = &b; - и указатель станет указывать на переменную b. - - Со ссылками такое не пройдёт, они всегда указывают на тот объект, который был указан при создании ссылки - При попытке изменить это и написать что-то вроде - r = b; - ссылка автоматически разыменуется и присваивание произойдёт к тому, на что указывала ссылка - - -*/ - -int main() -{ - int a = 10; - int b = 20; - - int* p = &a; - *p += 1; - p = &b; - *p += 1; - - cout << a << " " << b << endl; - - - int& r = a; - r += 1; - r = b; - r += 1; - - cout << a << " " << b << endl; -} - - -/* - Задачи: - - 1) Попробуйте понять, что напечатает программа без её запуска - - 2) Запустите программу, проверьте ваши догадки и объясните результат - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/05ref_pointer_diff_arith.cpp b/seminar01_overload/classroom_tasks/code/01ref/05ref_pointer_diff_arith.cpp deleted file mode 100644 index a4804a8..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/05ref_pointer_diff_arith.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Несмотря на то, что ссылки и указатели во многом похожи, у них есть и много больших отличий. - (помимо разной инициализации и того, что ссылку не нужно постоянно разыменовывать) - - Различие 4) - Арифметика указателей. - К указателю можно прибавлять/отнимать целые числа. Можно вычесть 2 указателя. - Можно применить [] к указателю. При всём этом, желательно, чтобы указатель указывал на элемент массива. - Неаккуратное использование арифметики указателей может привести к ошибкам. - Например, можно прибавить к указателю не то число и выйти за пределы массива. - - - Ничего такого со ссылками сделать нельзя. - При попытке прибавить к ссылке число, оно прибавится к той переменной, на которую указывает ссылка. - Так как ссылка автоматически разыменуется. - -*/ - -int main() -{ - int a[5] = {10, 20, 30, 40, 50}; - - int* p = &a[0]; - - p += 1; // Увеличиваем указатель - *p += 1; // Увеличиваем то, на что указывает указатель - - - int& r = a[0]; - - r += 1; // Увеличиваем то, на что указывает ссылка (она автоматически разыменовывается) -} - - -/* - Задачи: - - 1) Чему будет равен массив a в конце данной программы - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/06ref_restrictions.cpp b/seminar01_overload/classroom_tasks/code/01ref/06ref_restrictions.cpp deleted file mode 100644 index 5857823..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/06ref_restrictions.cpp +++ /dev/null @@ -1,46 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Несмотря на то, что ссылки и указатели во многом похожи, у них есть и много больших отличий. - - Различие 5) - Ссылки это не совсем обычный объект, некоторые операции с ними запрещены: - - Ссылку нельзя сделать элементом массива - - Нельзя получить адрес ссылки (если применим & то вернётся адрес того объекта на который указывет ссылка) - Нельзя создать укатель на ссылку - Нельзя создать ссылку на ссылку -*/ - -int main() -{ - - int x = 1; - int y = 2; - int z = 2; - - int& a[3] = {x, y, z}; // Ошибка, создать массив из ссылок не получится - -} - - -/* - Задачи: - - 1) Можно ли инициализировать ссылку на int простым числом вот так: - int& r = 5; - - - 2) Ссылку на ссылку создать нельзя, но код ниже почему-то работает. - Объясните почему этот код работает - - int a = 10; - int& r1 = a; - int& r2 = r1; - - r2 += 1; - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/07func_ref.cpp b/seminar01_overload/classroom_tasks/code/01ref/07func_ref.cpp deleted file mode 100644 index 55ec344..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/07func_ref.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - В 90% случаях ссылки используются для того чтобы передать что либо в функцию - Часто нам хочется передать переменную в функцию и изменить её там (внутри функции) - Это можно делать и с помощью указателей, но с помощью ссылок это делать гораздо удобней - Рассмотрим два эквивалентных участка кода: - - Передаём по указателю: Передаём по ссылке: - - void sqr(int* p) void sqr(int& r) - { { - *p = *p * *p; r = r * r; - } } - - int main() int main() - { { - int a = 5; int a = 5; - sqr(&a); sqr(a); - cout << a << endl; cout << a << endl; - } } - - - Обратите внимание на 2 вещи: - 1) Ссылку не нужно разыменовывать внутри функции, это происходит автоматически - - 2) При передаче в функцию, не нужно передавать адрес переменной - Нужно передать саму переменную, компилятор сам вычислит её адрес - - При этом копирования объекта a в функцию не происходит, - ссылки работают также быстро как и указатели -*/ - -void sqr(int& r) -{ - r = r * r; -} - -int main() -{ - int a = 5; - sqr(a); - - cout << a << endl; -} - - -/* - Задачи: - - 1) Напишите функцию void inc(int& x), которая должна принимать объект типа int - и увеличивать его на 1 - Вызовите эту функцию из main и протестируйте её работу - - 2) Напишите функцию void normalize(float& x, float& y), которая должна принимать - 2 объекта типа float и нормализировать их. То есть делить их на некоторое число, - так чтобы было x*x + y*y == 1 - - Для этого x и y нужно разделить на sqrt(x*x + y*y) - - - 3) Можно ли передать в функцию sqr не переменную, а число? - То есть, можно ли написать так: - sqr(5) - - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/07func_ref_solution.cpp b/seminar01_overload/classroom_tasks/code/01ref/07func_ref_solution.cpp deleted file mode 100644 index 9fcb592..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/07func_ref_solution.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include -using std::cout, std::endl; - - -void inc(int& x) -{ - x += 1; -} - -void normalize(float& x, float& y) -{ - float norm = std::sqrt(x * x + y * y); - x /= norm; - y /= norm; -} - - -int main() -{ - int a = 5; - inc(a); - cout << a << endl; - - float x = 9, y = 6; - normalize(x, y); - cout << x << " " << y << endl; -} - - -/* - Задачи: - - 1) Напишите функцию void inc(int& x), которая должна принимать объект типа int - и увеличивать его на 1 - Вызовите эту функцию из main и протестируйте её работу - - 2) Напишите функцию void normalize(float& x, float& y), которая должна принимать - 2 объекта типа float и нормализировать их. То есть делить их на некоторое число, - так чтобы было x*x + y*y == 1 - - Для этого x и y нужно разделить на sqrt(x*x + y*y) - - - 3) Можно ли передать в функцию sqr не переменную, а число? - То есть, можно ли написать так: - sqr(5) - - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/08func_ref_struct.cpp b/seminar01_overload/classroom_tasks/code/01ref/08func_ref_struct.cpp deleted file mode 100644 index 78ae781..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/08func_ref_struct.cpp +++ /dev/null @@ -1,81 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Чаще всего по ссылке в функцию передаются объекты структур и классов - - Даже если мы не хотим менять объект внутри функции, мы всё-равно можем - захотеть передать его по ссылке, так как передача по ссылке не копирует объект, - следовательно это гораздо более эффективно - - В этом случае передаём по константной ссылке (по аналогии с константным указателем) - -*/ - - -struct Book -{ - char title[100]; - int pages; - float price; -}; - - -void increasePrice(Book& b, float value) -{ - b.price += value; -} - -void printBook(Book& b) -{ - cout << b.title << ", pages = " << b.pages << ", price = " << b.price << endl; -} - - -int main() -{ - Book b = {"War and Peace", 1200, 900}; - - printBook(b); - increasePrice(b, 100); - printBook(b); -} - - -/* -// Тот же самый код с использованием указателей выглядел бы так: - -void increasePrice(Book* b, float value) -{ - b->price += value; -} - -void printBook(const Book* b) -{ - cout << b->title << ", pages = " << b->pages << ", price = " << b->price << endl; -} - -int main() -{ - Book b = {"War and Peace", 1200, 900}; - - printBook(&b); - increasePrice(b, 100); - printBook(&b); -} - -*/ - - -/* - Задачи: - - 1) Напишите функцию addPage, которая бы принимала структуру Book по ссылке - и увеличивала количество страниц на 1 - Протестируйте эту функцию в main - - 2) Напишите функцию changeFirstLetter, которая бы принимала структуру Book по ссылке - и изменяла первую букву в названии на букву A - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/08func_ref_struct_solution.cpp b/seminar01_overload/classroom_tasks/code/01ref/08func_ref_struct_solution.cpp deleted file mode 100644 index ebfceef..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/08func_ref_struct_solution.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include -using std::cout, std::endl; - - - -struct Book -{ - char title[100]; - int pages; - float price; -}; - -void addPage(Book& b) -{ - b.pages++; -} - -void changeFirstLetter(Book& b) -{ - b.title[0] = 'A'; -} - -void printBook(const Book& b) -{ - cout << b.title << ", pages = " << b.pages << ", price = " << b.price << endl; -} - - -int main() -{ - Book b = {"War and Peace", 1200, 900}; - - printBook(b); - - addPage(b); - printBook(b); - - changeFirstLetter(b); - printBook(b); -} - diff --git a/seminar01_overload/classroom_tasks/code/01ref/09by_value_pointer_ref.cpp b/seminar01_overload/classroom_tasks/code/01ref/09by_value_pointer_ref.cpp deleted file mode 100644 index baac9d3..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/09by_value_pointer_ref.cpp +++ /dev/null @@ -1,73 +0,0 @@ -#include -using std::cout, std::endl; - -/* - Ссылки, как и указатели используются для передачи объектов в функции - - Рассмотрим три функции - - incByValue - принимаем объект по значению - В этом случае объект копируется и функция работает с копией - - incByPointer - принимаем объект по адресу - В этом случае внутри функции создаётся указатель, и в этот указатель - мы передаём адрес нашего объекта - - incByReference - принимаем объект по ссылке - В этом случае происходит всё примерно то же самое, что и в случае incByPointer - Только с гораздо более приятным синтаксисом - -*/ - - -void incByValue(int a) -{ - a += 1; -} - -void incByPointer(int* p) -{ - *p += 1; -} - -void incByReference(int& a) -{ - a += 1; -} - -int main() -{ - int a = 10; - - cout << "1) Initial a = " << a << endl - - incByValue(a); - cout << "2) After incByValue a = " << a << endl; - - incByPointer(&a); - cout << "3) After incByPointer a = " << a << endl - - incByReference(a); - cout << "4) After incByReference a = " << a << endl; -} - - -/* - Задание: - - 1) Напишите функции: - - cubeByPointer(int* p) - принимет число по указателю и возводит это число в куб - cubeByReference(int& a) - принимет число по ссылке и возводит это число в куб - - Протестируйте эти функции в main - - - 2) Написать функции: - - swapByPointer(int* pa, int* pb) - принимает 2 числа по указателю и обменивает их значения - swap(int& pa, int& pb) - принимает 2 числа по ссылке и обменивает их значения - - Протестируйте эти функции в main - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/09by_value_pointer_ref_solution.cpp b/seminar01_overload/classroom_tasks/code/01ref/09by_value_pointer_ref_solution.cpp deleted file mode 100644 index 899e1c7..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/09by_value_pointer_ref_solution.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include -using std::cout, std::endl; - - -void cubeByPointer(int* p) -{ - *p = *p * *p * *p; -} - -void cubeByReference(int& a) -{ - a = a * a * a; -} - - -void swapByPointer(int* pa, int* pb) -{ - int temp = *pa; - *pa = *pb; - *pb = temp; -} - -void swapByReference(int& a, int& b) -{ - int temp = a; - a = b; - b = temp; -} - - - -int main() -{ - int a = 5; - cubeByPointer(&a); - cout << a << endl; - - a = 5; - cubeByReference(a); - cout << a << endl; - - - - int x = 10, y = 20; - swapByPointer(&x, &y); - cout << x << " " << y << endl; - - - x = 10; - y = 20; - swapByReference(x, y); - cout << x << " " << y << endl; - -} \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/10const_ref.cpp b/seminar01_overload/classroom_tasks/code/01ref/10const_ref.cpp deleted file mode 100644 index 3df3a6a..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/10const_ref.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include -#include -using std::cout, std::endl; - -/* - Константные ссылки можно создать, используя ключевое слово const - - int a = 10; - const int& r = a; - - Это означает, что a нельзя будет изменить по этой ссылке - То есть поменять a, используя ссылку r будет нельзя: - r += 1; // Ошибка! - a += 1; // OK - - - Важным неочевидным отличием константных ссылок от обычных ссылок является то, что обычные ссылки - можно инициализировать только объектами, которые уже храняться в памяти (например, переменными). - - int& r1 = a; // OK - int& r2 = 5; // Ошибка - - Константные ссылки можно инициализировать чем угодно (нужно только чтобы тип совпадал) - - const int& cr1 = a; // OK - const int& cr2 = 5; // OK - - -*/ - - -int main() -{ - int a = 10; - const int& r = a; - - - int& r1 = 20; // Это не будет компилироваться - const int& r2 = 20 // Тут всё ОК - -} - - -/* - Задание: - - 1) Можно ли инициализировать ссылку таким образом? - float& r = std::sqrt(2); - - Можно ли инициализировать константную ссылку таким образом? - const float& r = std::sqrt(2); - - - 2) Пусть есть функция: - - void printAgeV(int x) - { - cout << "My age is " << x << " years" << endl; - } - - Можно ли вызвать её так? - int a = 10; - printAgeV(a) - - Можно ли вызвать её так? - printAgeV(20) - - - 3) Пусть есть функция: - - void printAgeR(int& x) - { - cout << "My age is " << x << " years" << endl; - } - - Можно ли вызвать её так? - int a = 10; - printAgeR(a) - - Можно ли вызвать её так? - printAgeR(20) - - - 4) Пусть есть функция: - - void printAgeCR(const int& x) - { - cout << "My age is " << x << " years" << endl; - } - - Можно ли вызвать её так? - int a = 10; - printAgeCR(a) - - Можно ли вызвать её так? - printAgeCR(20) -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/10const_ref2.cpp b/seminar01_overload/classroom_tasks/code/01ref/10const_ref2.cpp deleted file mode 100644 index 9d1f484..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/10const_ref2.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include -#include -using std::cout, std::endl; - -/* - Константные ссылки нужны прежде всего, чтобы передавать большие объекты в функции, внутри которых они не должны меняться - - Рассмотрим структуру Book, чей размер более 100 байт - - - 1) При передаче такой структуры в функцию по значению, как это происходит в функции printBookV, - вся структура будет копироваться внутрь функции и это очень медленно. Так делать не стоит. - - - 2) При передаче такой структуры в функцию по обычной ссылке, как это происходит в функции printBookR, структура не копируется - На самом деле, под капотом внутрь функции копируется адрес структуры. - Адрес намного меньше самой структуры, поэтому это копирование работает намного быстрее. - - Но возникает проблема с тем, что структура внутри такой функции может поменяться. - В реальной ситуации, если функций много и они большие, уследить за тем меняется ли аргументы внутри функций становится проблематично. - - - 3) При передаче такой структуры в функцию по константной ссылке, как это происходит в функции printBookCR, структура не копируется. - Плюс к этому мы можем быть уверены, что внутри функции наша структура не поменяется и это сильно упрощает понимание программы. - -*/ - -struct Book -{ - char title[100]; - int pages; - float price; -}; - - -void printBookV(Book b) -{ - cout << b.title << ", pages = " << b.pages << ", price = " << b.price << endl; -} - - -void printBookR(Book& b) -{ - cout << b.title << ", pages = " << b.pages << ", price = " << b.price << endl; -} - - -void printBookCR(const Book& b) -{ - cout << b.title << ", pages = " << b.pages << ", price = " << b.price << endl; -} - - -int main() -{ - Book b = {"War and Peace", 1200, 900}; - - printBookV(b); - printBookR(b); - printBookCR(b); -} - - diff --git a/seminar01_overload/classroom_tasks/code/01ref/11return_ref.cpp b/seminar01_overload/classroom_tasks/code/01ref/11return_ref.cpp deleted file mode 100644 index 8436ff0..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/11return_ref.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Ссылки можно и возвращать из функции - Например, функция get возвращает ссылку на глобальную переменную x - -*/ - -int x = 10; - - -int& get() -{ - return x; -} - -int main() -{ - cout << x << endl; - cout << get() << endl; - - get() += 1; - cout << x << endl; -} - - - -/* - С указателями аналогичный код выглядел бы так: - - -int x = 10; - -int* get() -{ - return &x; -} - -int main() -{ - cout << x << endl; - cout << *get() << endl; - - *get() += 1; - cout << x << endl; -} - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/12return_ref_local.cpp b/seminar01_overload/classroom_tasks/code/01ref/12return_ref_local.cpp deleted file mode 100644 index 8b15dbc..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/12return_ref_local.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Ссылки можно и возвращать из функции - - Но при этом нужно следить за тем, чтобы функция не вернула ссылку на локальную переменную, как это происходит в данном примере. - После завершения функции, переменная x удалится, так как она была определена внутри функции. - - В результате, внутри функции main мы попробуем доступиться к области памяти, в которой раньше лежала переменная x. - Это приведёт к ошибке - -*/ - -int& get() -{ - int x = 10; - return x; -} - - -int main() -{ - cout << get() << endl; - - get() += 1; - cout << get() << endl; - -} - - - -/* - Аналогичная ошибка может произойти и при работе с обычными указателями: - - int* get() - { - int x = 10; - return &x; - } - - int main() - { - cout << *get() << endl; - - *get() += 1; - cout << *get() << endl; - } - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/13return_ref_argument.cpp b/seminar01_overload/classroom_tasks/code/01ref/13return_ref_argument.cpp deleted file mode 100644 index ce7b9e3..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/13return_ref_argument.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Ссылки можно и возвращать из функции - Например, функция increase принимает ссылку, увеличивет то, на что указывает эта ссылка на 1 - и возвращает эту ссылку - - При этом никакого копирование самой переменной a в функцию и из функции не происходит -*/ - -int& increase(int& r) -{ - r += 1; - return r; -} - -int main() -{ - int a = 10; - - cout << "1) a = " << a << endl; - - increase(a); - cout << "2) a = " << a << endl; - - increase(a) += 7; - cout << "3) a = " << a << endl; - - increase(increase(increase(a))); - cout << "4) a = " << a << endl; -} - - - -/* - Что напечатает данная программа? -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/01ref/14problem_1.cpp b/seminar01_overload/classroom_tasks/code/01ref/14problem_1.cpp deleted file mode 100644 index 8458de8..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/14problem_1.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Задача: - - Напишите функцию multiplyBy2, которая принимает число по ссылке и увеличивает его в 2 раза - Вызовите эту функцию из функции main - -*/ - -int main() -{ - -} - diff --git a/seminar01_overload/classroom_tasks/code/01ref/14problem_1_solution.cpp b/seminar01_overload/classroom_tasks/code/01ref/14problem_1_solution.cpp deleted file mode 100644 index 8a264b1..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/14problem_1_solution.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include -using std::cout, std::endl; - - -void multiplyBy2(int& a) -{ - a *= 2; -} - -int main() -{ - int x = 10; - multiplyBy2(x); - cout << x << endl; -} - diff --git a/seminar01_overload/classroom_tasks/code/01ref/15problem_2.cpp b/seminar01_overload/classroom_tasks/code/01ref/15problem_2.cpp deleted file mode 100644 index 39c5515..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/15problem_2.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Задача: - - Напишите функцию sumAndSave, которая должна принимать 3 аргумента - Первые два аргумента по значению - Третий аргумент по ссылке - - Функция должна складывать первые 2 аргумента и сохранять результат по третей ссылке - - Вызовите эту функцию из функции main - -*/ - -int main() -{ - -} - diff --git a/seminar01_overload/classroom_tasks/code/01ref/15problem_2_solution.cpp b/seminar01_overload/classroom_tasks/code/01ref/15problem_2_solution.cpp deleted file mode 100644 index dffaf64..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/15problem_2_solution.cpp +++ /dev/null @@ -1,36 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Задача: - - Напишите функцию sumAndSave, которая должна принимать 3 аргумента - Первые два аргумента по значению - Третий аргумент по ссылке - - Функция должна складывать первые 2 аргумента и сохранять результат по третей ссылке - - Вызовите эту функцию из функции main - -*/ - -void sumAndSave(int a, int b, int& c) -{ - c = a + b; -} - - -int main() -{ - int x = 10, y = 20; - int z; - - sumAndSave(x, y, z); - cout << z << endl; - - - sumAndSave(70, 80, z); - cout << z << endl; -} - diff --git a/seminar01_overload/classroom_tasks/code/01ref/15problem_3.cpp b/seminar01_overload/classroom_tasks/code/01ref/15problem_3.cpp deleted file mode 100644 index 844c8cc..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/15problem_3.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Задача: - - Напишите функцию - - void calculateLetters(char str[], int& numLetters) - - Которая будет принимать на вход строку и считать количество строчных букв в этой строке - Строчные буквы - это символы от 'a' и до 'z' - - Например, вызов calculateLetters("ab54AB,gd1:e", x) должен сохранить число 5 в переменную x - - -*/ - -int main() -{ - - int x; - calculateLetters("ab54AB,gd1:e", x); - cout << x << endl; - -} - diff --git a/seminar01_overload/classroom_tasks/code/01ref/15problem_3_solution.cpp b/seminar01_overload/classroom_tasks/code/01ref/15problem_3_solution.cpp deleted file mode 100644 index 7cf9e5c..0000000 --- a/seminar01_overload/classroom_tasks/code/01ref/15problem_3_solution.cpp +++ /dev/null @@ -1,23 +0,0 @@ -#include -using std::cout, std::endl; - - - - -void calculateLetters(char str[], int& numLetters) -{ - numLetters = 0; - for (int i = 0; str[i] != '\0'; ++i) - { - if (str[i] >= 'a' && str[i] <= 'z') - numLetters += 1; - } -} - -int main() -{ - int x; - calculateLetters("ab54AB,gd1:e", x); - cout << x << endl; -} - diff --git a/seminar01_overload/classroom_tasks/code/02function_overload/00c_functions.c b/seminar01_overload/classroom_tasks/code/02function_overload/00c_functions.c deleted file mode 100644 index b478e0b..0000000 --- a/seminar01_overload/classroom_tasks/code/02function_overload/00c_functions.c +++ /dev/null @@ -1,61 +0,0 @@ -#include - -/* - Это программа на языке C и компилировать её надо так: - gcc 00cfunctions.c - - - Известно, что в языке C нельзя создать две функции с одинаковым названием - Но часто требуется написать функции, которые будут делать похожие вещи, но для разных типов данных. - Простейший пример -- математические функции для разных численных типов данных - - В языке C эта проблема решается так, что функциям даются немного различающиеся имена - - - В данном примере мы создали функции для вычисления абсолютного значения для типов int и double - Всё работает хорошо, пока мы соблюдаем типы данных и функции - - Но стоит ошибиться и произойдёт сложно выявляемая ошибка - -*/ - -int abs(int a) -{ - if (a < 0) - return -a; - else - return a; -} - -double fabs(double a) -{ - if (a < 0) - return -a; - else - return a; -} - - - - -int main() -{ - printf("%i\n", abs(-5)); - printf("%lf\n", fabs(-5.9)); - - - double x = abs(-5.9); - printf("%lf\n", x); -} - - - - -/* - Задача: - - 1) В данном примере переменная x равна ровно 5. Почему так происходит? - - 2) Что будет, если всё-таки назвать 2 функции одинаковым именем и скомпилировать программу с помощью gcc? - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/02function_overload/01cpp_functions.cpp b/seminar01_overload/classroom_tasks/code/02function_overload/01cpp_functions.cpp deleted file mode 100644 index ecd9016..0000000 --- a/seminar01_overload/classroom_tasks/code/02function_overload/01cpp_functions.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include -using std::cout, std::endl; - -/* - Это программа на языке C++ и компилировать её надо так: - g++ 01cppfunctions.c - - - В отличии от языка C в языке C++ есть возможность создать 2 и больше разных функции с одним и тем же названием, - но с разным количеством и/или типами аргументов. - - Компилятор сам догадается, какую функцию следует вызвать в зависимости от типа аргумента. - -*/ - -int abs(int a) -{ - if (a < 0) - return -a; - else - return a; -} - -double abs(double a) -{ - if (a < 0) - return -a; - else - return a; -} - - - - -int main() -{ - cout << abs(-5) << endl; - cout << abs(-5.9) << endl; - - - double x = abs(-5.9); - cout << x << endl; -} - - - - -/* - Задачи: - - 1) Протестируйте, что компилятор действительно вызывает нужные функции - Для этого просто сделайте так, чтобы функция, которая принимает int печатала на экран слово int, - а функция, которая принимает double, печатала бы на экран слово double - - - 2) Что если на вход функции abs передать тип float? - Например, вот так: - abs(1.5f) - - Какая из функций вызовется? - - - 3) Напишите ещё одну перегрузку функции abs для типа float - Протестируйте её в функции main - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/02function_overload/02problem.cpp b/seminar01_overload/classroom_tasks/code/02function_overload/02problem.cpp deleted file mode 100644 index a748b3d..0000000 --- a/seminar01_overload/classroom_tasks/code/02function_overload/02problem.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include -using std::cout, std::endl; - -/* - Задача: - - Напишите несколько перегруженных функций под названием max - - 1) max, который вычисляет максимум от двух чисел типа int - 2) max, который вычисляет максимум от двух чисел типа double - 3) max, который вычисляет максимум от трёх чисел типа int - 4) max, который вычисляет максимум от трёх чисел типа double - -*/ - -int max(int a, int b) -{ - if (a > b) - return a; - else - return b; -} - - - - -int main() -{ - cout << max(4.2, 2.8) << endl; // Выводит число 4 -- неправильно -} \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/02function_overload/02problem_solution.cpp b/seminar01_overload/classroom_tasks/code/02function_overload/02problem_solution.cpp deleted file mode 100644 index 26ae5aa..0000000 --- a/seminar01_overload/classroom_tasks/code/02function_overload/02problem_solution.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include -using std::cout, std::endl; - - -int max(int a, int b) -{ - if (a > b) - return a; - else - return b; -} - -double max(double a, double b) -{ - if (a > b) - return a; - else - return b; -} - -int max(int a, int b, int c) -{ - int result = a; - if (b > result) - result = b; - if (c > result) - result = c; - return result; -} - -double max(double a, double b, double c) -{ - double result = a; - if (b > result) - result = b; - if (c > result) - result = c; - return result; -} - - - - -int main() -{ - cout << max(4.2, 2.8) << endl; - - cout << max(1, 2) << endl; - - cout << max(4, 2, 5) << endl; - - cout << max(1.2, 2.1, 0.5) << endl; -} \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/02function_overload/03problem.cpp b/seminar01_overload/classroom_tasks/code/02function_overload/03problem.cpp deleted file mode 100644 index 740f833..0000000 --- a/seminar01_overload/classroom_tasks/code/02function_overload/03problem.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include -using std::cout, std::endl; - -/* - Задача: - - Напишите несколько перегруженных функций под названием printType - - Эти функции должны печатать тип переменной, которая поступает на вход - - - printType(15) должен напечатать int - printType(1.5) должен напечатать double - printType(1.5f); должен напечатать float - printType("Hello"); должен напечатать char[] - - book b = {"War and Peace", 900, 1200}; - printType(b); должен напечатать book - -*/ - -struct book -{ - char title[50]; - float price; - int pages; -}; - - - - - -int main() -{ - printType(15); - printType(1.5); - printType(1.5f); - printType("Hello"); - - book b = {"War and Peace", 900, 1200}; - printType(b); -} \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/02function_overload/03problem_solution.cpp b/seminar01_overload/classroom_tasks/code/02function_overload/03problem_solution.cpp deleted file mode 100644 index a8e3098..0000000 --- a/seminar01_overload/classroom_tasks/code/02function_overload/03problem_solution.cpp +++ /dev/null @@ -1,66 +0,0 @@ -#include -using std::cout, std::endl; - -/* - Задача: - - Напишите несколько перегруженных функций под названием printType - - Эти функции должны печатать тип переменной, которая поступает на вход - - - printType(15) должен напечатать int - printType(1.5) должен напечатать double - printType(1.5f); должен напечатать float - printType("Hello"); должен напечатать char[] - - book b = {"War and Peace", 900, 1200}; - printType(b); должен напечатать book - -*/ - -struct book -{ - char title[50]; - float price; - int pages; -}; - - -void printType(int a) -{ - cout << "int" << endl; -} - -void printType(double a) -{ - cout << "double" << endl; -} - -void printType(float a) -{ - cout << "float" << endl; -} - -void printType(const char a[]) -{ - cout << "char[]" << endl; -} - -void printType(const book& a) -{ - cout << "book" << endl; -} - - - -int main() -{ - printType(15); - printType(1.5); - printType(1.5f); - printType("Hello"); - - book b = {"War and Peace", 900, 1200}; - printType(b); -} \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/02function_overload/04std.cpp b/seminar01_overload/classroom_tasks/code/02function_overload/04std.cpp deleted file mode 100644 index 136311a..0000000 --- a/seminar01_overload/classroom_tasks/code/02function_overload/04std.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include -using std::cout, std::endl; - -/* - В отличии от языка C в языке C++ стандартные математические функции уже перегружены и могут - работать с разными типами данных -*/ - - - -int main() -{ - cout << std::abs(-4) << endl; - cout << std::abs(-4.2) << endl; - cout << std::abs(-4.2f) << endl; -} \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/02function_overload/05ref_overload.cpp b/seminar01_overload/classroom_tasks/code/02function_overload/05ref_overload.cpp deleted file mode 100644 index 65c2f55..0000000 --- a/seminar01_overload/classroom_tasks/code/02function_overload/05ref_overload.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include -using std::cout, std::endl; - -/* - Функции можно перегружать и по указателю и ссылке - - Но в случае с перегрузкой по ссылке могут возникнуть ситуации при которых невозможно выбрать правильный - - Например, при вызове - - int a = 10; - func(a); - - Можно выбрать функцию void func(int x) или void func(int& x) - Определить более правильную функцию в этом случае невозможно, это приведёт к ошибке -*/ - - -void func(int x) -{ - cout << "int x" << endl; -} - -void func(int* x) -{ - cout << "int* x" << endl; -} - - -void func(int& x) -{ - cout << "int& x" << endl; -} - - -int main() -{ - int a = 10; - int* p = &a; - int& r = a; - - func(a); -} - - -/* - Задачи: - - 1) Определите какая функция вызовется при следующих вызовах функции func или произойдёт ошибка - - 1) func(a) - 2) func(p) - 3) func(&a) - 4) func(20) - 5) func(r) - 6) func(&r) - - - 2) Если добавить перегрузку, принимающую по константной ссылке, то что изменится - - void func(const int& x) - { - cout << "const int& x" << endl; - } - - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/02function_overload/animals.cpp b/seminar01_overload/classroom_tasks/code/02function_overload/animals.cpp deleted file mode 100644 index 6b80feb..0000000 --- a/seminar01_overload/classroom_tasks/code/02function_overload/animals.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include -using std::cout, std::endl; - -struct Cat {}; -struct Dog {}; -struct Cow {}; - - - -void say(Cat a) -{ - cout << "Meow" << endl; -} - -void say(Dog a) -{ - cout << "Woof" << endl; -} - -void say(Cow a) -{ - cout << "Mooo" << endl; -} - - -int main() -{ - Cow x; - say(x); -} \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/03operator_overload/00no_operator_overload.cpp b/seminar01_overload/classroom_tasks/code/03operator_overload/00no_operator_overload.cpp deleted file mode 100644 index 923d93b..0000000 --- a/seminar01_overload/classroom_tasks/code/03operator_overload/00no_operator_overload.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Предположим, что мы захотели создать структуру, который будет хранить время (для простоты, только минуты и секунды) - - Нам может понадобиться функция, которая будет добавлять ко времени, некоторое количество секунд - -*/ - - -struct Time -{ - int minutes; - int seconds; -}; - -Time add(Time t, int x) -{ - Time result = t; - result.seconds += x; - - result.minutes += (result.seconds / 60); - result.seconds %= 60; - - return result; -} - - -int main() -{ - Time a = {20, 10}; - Time b = add(a, 90); - - cout << b.minutes << " " << b.seconds << endl; -} - - -/* - - Задача: - - 1) Напишите функцию, которая будет складывать не время и число, а два времени - - Time add(Time ta, Time tb) - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/03operator_overload/00no_operator_overload_solution.cpp b/seminar01_overload/classroom_tasks/code/03operator_overload/00no_operator_overload_solution.cpp deleted file mode 100644 index 07d04d3..0000000 --- a/seminar01_overload/classroom_tasks/code/03operator_overload/00no_operator_overload_solution.cpp +++ /dev/null @@ -1,44 +0,0 @@ -#include -using std::cout, std::endl; - - -struct Time -{ - int minutes; - int seconds; -}; - -Time add(Time t, int x) -{ - Time result = t; - result.seconds += x; - - result.minutes += (result.seconds / 60); - result.seconds %= 60; - - return result; -} - - -Time add(Time ta, Time tb) -{ - Time result = ta; - result.seconds += 60 * tb.minutes + tb.seconds; - - result.minutes += (result.seconds / 60); - result.seconds %= 60; - - return result; -} - - -int main() -{ - Time a = {20, 10}; - Time b = add(a, 90); - Time c = add(a, b); - - cout << b.minutes << " " << b.seconds << endl; - cout << c.minutes << " " << c.seconds << endl; -} - diff --git a/seminar01_overload/classroom_tasks/code/03operator_overload/01_operator_overload.cpp b/seminar01_overload/classroom_tasks/code/03operator_overload/01_operator_overload.cpp deleted file mode 100644 index 2b7275f..0000000 --- a/seminar01_overload/classroom_tasks/code/03operator_overload/01_operator_overload.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Использовать функции может быть не так удобно как операторы. - Возможно было бы удобней для добавления времени использовать не функцию add, а оператор + - - Можно перегрузить оператор функцией, для этого нужно назвать функцию так: operator@ - где за место @ нужно подставить оператор, который вы хотите перегрузить - - Например, функция Time operator+(Time t, int x) перегружает оператор + для типов Time и int соответственно (обязательно в таком порядке) - Теперь, когда компилятор встретит в коде сложение с таким операндами он вызовет эту функцию - - В этом примере a + 90 при компиляции преобразуется в вызов функции operator+(a, 90) - -*/ - - -struct Time -{ - int minutes; - int seconds; -}; - -Time operator+(Time t, int x) -{ - Time result = t; - result.seconds += x; - - result.minutes += (result.seconds / 60); - result.seconds %= 60; - - return result; -} - - -int main() -{ - Time a = {20, 10}; - Time b = a + 90; - - cout << b.minutes << " " << b.seconds << endl; -} - - -/* - - Задача: - - 1) Что если операторы сложения поменяются местами - Time b = 90 + a; - Сработает ли в этом случае наша функция operator+ и, если нет, что нужно добавить, чтобы такое сложение сработало? - - - 2) Напишите перегруженный оператор, который будет складывать не время и число, а два времени - - Time operator+(Time ta, Time tb) - - - - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/03operator_overload/01_operator_overload_solution.cpp b/seminar01_overload/classroom_tasks/code/03operator_overload/01_operator_overload_solution.cpp deleted file mode 100644 index 1b5d7af..0000000 --- a/seminar01_overload/classroom_tasks/code/03operator_overload/01_operator_overload_solution.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include -using std::cout, std::endl; - - -struct Time -{ - int minutes; - int seconds; -}; - -Time operator+(Time t, int x) -{ - Time result = t; - result.seconds += x; - - result.minutes += (result.seconds / 60); - result.seconds %= 60; - - return result; -} - -Time operator+(int x, Time t) -{ - return t + x; -} - -Time operator+(Time ta, Time tb) -{ - Time result = ta; - result.seconds += 60 * tb.minutes + tb.seconds; - - result.minutes += (result.seconds / 60); - result.seconds %= 60; - - return result; -} - - -int main() -{ - Time a = {20, 10}; - Time b = a + 90; - Time c = 90 + a; - Time d = a + b; - - cout << b.minutes << " " << b.seconds << endl; - cout << c.minutes << " " << c.seconds << endl; - cout << d.minutes << " " << d.seconds << endl; - -} diff --git a/seminar01_overload/classroom_tasks/code/03operator_overload/02_operator_unary.cpp b/seminar01_overload/classroom_tasks/code/03operator_overload/02_operator_unary.cpp deleted file mode 100644 index 2c8dac3..0000000 --- a/seminar01_overload/classroom_tasks/code/03operator_overload/02_operator_unary.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Помимо перегрузки операторов, принимающих 2 аргумента (бинарных) - можно перегружать и унарные операторы - принимающие один аргумент - - При этом, так как operator+ это функция, то работает перегрузка функций - - -*/ - - -struct Time -{ - int minutes; - int seconds; -}; - -Time operator+(Time ta, Time tb) -{ - cout << "binary operator +" << endl; - - Time result = ta; - result.seconds += 60 * tb.minutes + tb.seconds; - - result.minutes += (result.seconds / 60); - result.seconds %= 60; - - return result; -} - -Time operator+(Time t) -{ - cout << "unary operator +" << endl; - - return t; -} - - -int main() -{ - Time a = {20, 10}; - Time b = {40, 30}; - - Time c = a + b; - Time d = +a; - - cout << c.minutes << " " << c.seconds << endl; - cout << d.minutes << " " << d.seconds << endl; -} - - -/* - - Задача: - - 1) Что если операторы сложения поменяются местами - Time b = 90 + a; - Сработает ли в этом случае наша функция operator+ и, если нет, что нужно добавить, чтобы такое сложение сработало? - - - 2) Напишите перегруженный оператор, который будет складывать не время и число, а два времени - - Time operator+(Time ta, Time tb) - - - - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/03operator_overload/03bool.cpp b/seminar01_overload/classroom_tasks/code/03operator_overload/03bool.cpp deleted file mode 100644 index 3925c8f..0000000 --- a/seminar01_overload/classroom_tasks/code/03operator_overload/03bool.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include -using std::cout, std::endl; - -/* - В прошлом семестре, для хранения результатов логических операций, мы использовали целочисленные типы (например int). - - В языке C++ есть встроенный тип bool, который может принимать 2 значения (true и false). - Для хранения значения логических переменных желательно использовать этот тип - - - При печати на экран с помощью std::cout переменных типа bool печатается либо 0 либо 1 - Чтобы на экран печаталось false или true нужно в std::cout передать специальный объект std::boolalpha - -*/ - - -bool isEven(int a) -{ - return a % 2 == 0; -} - -int main() -{ - bool a = isEven(10); - bool b = isEven(15); - bool c = a || b; - - - if (c) - cout << "Yes" << endl; - else - cout << "No" << endl; - - cout << c << endl; - cout << std::boolalpha << c << endl; -} - - diff --git a/seminar01_overload/classroom_tasks/code/03operator_overload/04_comparison_operators.cpp b/seminar01_overload/classroom_tasks/code/03operator_overload/04_comparison_operators.cpp deleted file mode 100644 index 6d8204a..0000000 --- a/seminar01_overload/classroom_tasks/code/03operator_overload/04_comparison_operators.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Помимо арифметических операторов можно перегружать и операторы сравнения (и многие другие операторы) - Желательно, чтобы операторы сравнения возвращали bool -*/ - - -struct Time -{ - int minutes; - int seconds; -}; - -Time operator+(Time ta, Time tb) -{ - Time result = ta; - result.seconds += 60 * tb.minutes + tb.seconds; - - result.minutes += (result.seconds / 60); - result.seconds %= 60; - - return result; -} - - -bool operator>(Time ta, Time tb) -{ - bool result = false; - - if (ta.minutes > tb.minutes) - result = true; - else if (ta.minutes == tb.minutes && ta.seconds > tb.seconds) - result = true; - - return result; -} - - -int main() -{ - Time a = {10, 20}; - Time b = {10, 40}; - Time c = {0, 20}; - - cout << std::boolalpha; - cout << (a > b) << endl; - cout << (b > a) << endl; - cout << (a + c > b) << endl; -} - - -/* - - Задача: - - 1) Заметьте, что при выводе на экран сравнение было взято в скобки - cout << (a > b) << endl; - - Что будет, если эти скобки не писать и почему - cout << a > b << endl; - - - 2) Напишите перегруженные операторы < >= <= == != для сравнения объектов структур типа Time друг с другом - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/03operator_overload/04_comparison_operators_solution.cpp b/seminar01_overload/classroom_tasks/code/03operator_overload/04_comparison_operators_solution.cpp deleted file mode 100644 index d0d2431..0000000 --- a/seminar01_overload/classroom_tasks/code/03operator_overload/04_comparison_operators_solution.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include -using std::cout, std::endl; - - -/* - Помимо арифметических операторов можно перегружать и операторы сравнения (и многие другие операторы) - Желательно, чтобы операторы сравнения возвращали bool -*/ - - -struct Time -{ - int minutes; - int seconds; -}; - -Time operator+(Time ta, Time tb) -{ - Time result = ta; - result.seconds += 60 * tb.minutes + tb.seconds; - - result.minutes += (result.seconds / 60); - result.seconds %= 60; - - return result; -} - - -bool operator>(Time ta, Time tb) -{ - bool result = false; - - if (ta.minutes > tb.minutes) - result = true; - else if (ta.minutes == tb.minutes && ta.seconds > tb.seconds) - result = true; - - return result; -} - - -bool operator==(Time ta, Time tb) -{ - bool result = false; - if (ta.minutes == tb.minutes && ta.seconds == tb.seconds) - result = true; - - return result; -} - -bool operator!=(Time ta, Time tb) -{ - return !(ta == tb); -} - - -bool operator>=(Time ta, Time tb) -{ - return ta > tb || ta == tb; -} - - -bool operator<(Time ta, Time tb) -{ - return !(ta >= tb); -} - - -bool operator<=(Time ta, Time tb) -{ - return !(ta > tb); -} - - - - - -int main() -{ - Time a = {10, 20}; - Time b = {10, 40}; - Time c = {0, 20}; - - cout << std::boolalpha; - cout << (a == b) << endl; - cout << (a != b) << endl; - - cout << (a < b) << endl; - cout << (a <= b) << endl; - cout << (a > b) << endl; - cout << (a >= b) << endl; - cout << (a + c >= b) << endl; -} - - -/* - - Задача: - - 1) Заметьте, что при выводе на экран сравнение было взято в скобки - cout << (a > b) << endl; - - Что будет, если эти скобки не писать и почему - cout << a > b << endl; - - Ошибка происходит из-за того, что приоритет операции << выше, чем у операций сравнения - В результате сначала проводится - cout << a - затем получившийся объект сравнивается с b. Это и приводит к ошибке. -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/03operator_overload/05iostream_overload.cpp b/seminar01_overload/classroom_tasks/code/03operator_overload/05iostream_overload.cpp deleted file mode 100644 index 05fd9eb..0000000 --- a/seminar01_overload/classroom_tasks/code/03operator_overload/05iostream_overload.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include -using std::cout, std::endl; - -/* - Перегрузка оператора << для вывода на экран - - Напомним, что объект под названием cout имеет тип ostream (сокращение от output stream - выходной поток) - и хранится в библиотеке iostream в пространстве имён std - - То есть где-то внутри библиотеки iostream объявлена глобальная переменная по имени cout типа ostream - ostream cout; - - - Мы можем перегрузить оператор << с первым аргументом типа std::ostream, а вторым аргументом - нашим типом, - чтобы удобно выводить на экран объекты нашего типа. - -*/ - - - -struct Time -{ - int minutes; - int seconds; -}; - - -void operator<<(std::ostream& out, Time t) -{ - out << t.minutes << ":" << t.seconds; -} - - -int main() -{ - Time a = {10, 20}; - cout << a; -} - - -/* - Задача: - - cout << a; работает, но - cout << a << endl; выдаёт ошибку в данной программе. - - Из-за чего это происходит и как исправить эту ошибку? - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/03operator_overload/05iostream_overload_solution.cpp b/seminar01_overload/classroom_tasks/code/03operator_overload/05iostream_overload_solution.cpp deleted file mode 100644 index c035ba0..0000000 --- a/seminar01_overload/classroom_tasks/code/03operator_overload/05iostream_overload_solution.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include -using std::cout, std::endl; - - - -struct Time -{ - int minutes; - int seconds; -}; - - -Time operator+(Time ta, Time tb) -{ - Time result = ta; - result.seconds += 60 * tb.minutes + tb.seconds; - - result.minutes += (result.seconds / 60); - result.seconds %= 60; - - return result; -} - - -std::ostream& operator<<(std::ostream& out, Time t) -{ - out << t.minutes << ":" << t.seconds; - return out; -} - - -int main() -{ - Time a = {10, 20}; - Time b = {15, 50}; - - cout << a << endl << b << endl; - cout << a + b << endl; -} - - -/* - Задача: - - cout << a; работает, но - cout << a << endl; выдаёт ошибку в данной программе. - - Из-за чего это происходит и как исправить эту ошибку? - - - Решение: - - Ошибка происходила из-за того, что оператор << ничего не возвращал. - - В строке cout << a << endl; - результат cout << a был void и к нему нельзя применить оператор << ещё раз. - - - Результат cout << a должен быть тоже быть равен cout - Но, поскольку глобальный объект cout копировать мы не можем, у нас остаётся единственный выход: - принимать и возвращать объект cout по ссылке. - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/03operator_overload/06operator_overload.cpp b/seminar01_overload/classroom_tasks/code/03operator_overload/06operator_overload.cpp deleted file mode 100644 index bdfcbfe..0000000 --- a/seminar01_overload/classroom_tasks/code/03operator_overload/06operator_overload.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include -using std::cout, std::endl; - -struct Complex -{ - float re, im; -}; - -Complex operator+(Complex first, Complex second) -{ - Complex result = {first.re + second.re, first.im + second.im}; - return result; -} - -int main() -{ - Complex z1 = {3, 7}; - Complex z2 = {2, -4}; - - Complex z = z1 + z2; - cout << z.re << " + " << z.im << "i" << endl; -} - -/* - Задачи: - - 1) Перегрузите следующие операторы: - - Вычитание - - Умножение - - Деление - - Унарный минус - - Унарный плюс - - Сравнение == - - Сопряжение - это операция, которая меняет знак мнимой части комплексного числа - Для сопряжения используйте оператор унарная звёздочка * - - 2) Перегрузите оператор вывода << - - 3) Напишите функцию exp(z) - - - - /* - cout << z1 - z2 << endl; - cout << z1 * z2 << endl; - cout << z1 / z2 << endl; - cout << -z1 << endl; - cout << *z1 << endl; // (Комплексно-сопряжённое) - - z = exp(z1 + z2)/(z1 * z2); - cout << z << endl; - */ diff --git a/seminar01_overload/classroom_tasks/code/03operator_overload/setw.cpp b/seminar01_overload/classroom_tasks/code/03operator_overload/setw.cpp deleted file mode 100644 index 27afe6a..0000000 --- a/seminar01_overload/classroom_tasks/code/03operator_overload/setw.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -using std::cout, std::endl; - - -/* - В библиотеки iomanip содержатся специальные функции, для работы с потоками ostream - - setw - установить минимальный размер в символах для печати следующего объекта - setfill - если размер печати меньше минимального, то замостить оставшееся соответствующим символом - - setprecision - установить точность (для вещественных чисел) -*/ - - -struct Time -{ - int minutes; - int seconds; -}; - - -Time operator+(Time ta, Time tb) -{ - Time result = ta; - result.seconds += 60 * tb.minutes + tb.seconds; - - result.minutes += (result.seconds / 60); - result.seconds %= 60; - - return result; -} - - -std::ostream& operator<<(std::ostream& out, Time t) -{ - out << std::setfill('0') << std::setw(2) << t.minutes << ":" << - std::setfill('0') << std::setw(2) << t.seconds; - return out; -} - - -int main() -{ - Time a = {1, 5}; - Time b = {4, 20}; - - cout << a << endl << b << endl; - cout << a + b << endl; -} - - diff --git a/seminar01_overload/classroom_tasks/code/04other/00pointer_cast.cpp b/seminar01_overload/classroom_tasks/code/04other/00pointer_cast.cpp deleted file mode 100644 index 8d17b7a..0000000 --- a/seminar01_overload/classroom_tasks/code/04other/00pointer_cast.cpp +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include -using std::cout, std::endl; - - -/* - В отличии от языка C, язык C++ не делает неявное преобразование типов указателей. - - Рассмотрим, например, код: - - int a = 10; - char* p = &a; - - В языке C такой код сработает, несмотря на то, что в строке char* p = &a; слева стоит указатель типа char* - а справа объект типа int*. Будет произведено неявное преобразование типов указателей. - - В языке C++ такой код приведёт к ошибке, так как C++ не преобразует указатели неявно. - - - - Рассмотрим, например, код: - - int* q = malloc(10 * sizeof(int)); - - В языке C такой код сработает, несмотря на то, что слева стоит указатель типа int* - а справа объект типа void* (malloc возвращает указатель типа void*). - Будет произведено неявное преобразование типов указателей. - - В языке C++ такой код приведёт к ошибке, так как C++ не преобразует указатели неявно. -*/ - - - -int main() -{ - int a = 10; - char* p = &a; - - - int* q = malloc(10 * sizeof(int)); -} - - - - -/* - - Задача: - - Исправьте ошибки компиляции, явно приведя указатель к правильным типам. - -*/ \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/04other/00pointer_cast_solution1.cpp b/seminar01_overload/classroom_tasks/code/04other/00pointer_cast_solution1.cpp deleted file mode 100644 index af90543..0000000 --- a/seminar01_overload/classroom_tasks/code/04other/00pointer_cast_solution1.cpp +++ /dev/null @@ -1,13 +0,0 @@ -#include -#include -using std::cout, std::endl; - - -int main() -{ - int a = 10; - char* p = (char*)&a; - - - int* q = (int*)malloc(10 * sizeof(int)); -} \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/04other/00pointer_cast_solution2.cpp b/seminar01_overload/classroom_tasks/code/04other/00pointer_cast_solution2.cpp deleted file mode 100644 index 1ab4b63..0000000 --- a/seminar01_overload/classroom_tasks/code/04other/00pointer_cast_solution2.cpp +++ /dev/null @@ -1,17 +0,0 @@ -#include -#include -using std::cout, std::endl; - - -/* - В языке C++ желательно использовать более безопасное приведение типов static_cast -*/ - -int main() -{ - int a = 10; - char* p = static_cast(&a); - - - int* q = static_cast(malloc(10 * sizeof(int))); -} \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/04other/01nulptr.cpp b/seminar01_overload/classroom_tasks/code/04other/01nulptr.cpp deleted file mode 100644 index 7230ba4..0000000 --- a/seminar01_overload/classroom_tasks/code/04other/01nulptr.cpp +++ /dev/null @@ -1,50 +0,0 @@ -#include - -/* - Новое специальное нулевое значение для указателя: nullptr - В языке C для этой цели использовался NULL, который был просто числом 0 - - Если определить NULL так: - - #define NULL (void*)0 - - То, в отличии от языка C, в языке C++ простая строка вида: - - int* p = NULL; - - не сработает, так как слева стоит int* а справа void* - - - Если определить NULL так: - - #define NULL 0 - - то в C++ могут возникнуть проблемы с перегрузкой, как это показано ниже. - -*/ - -void print(int value) -{ - printf("Int: %d\n", value); -} - -void print(void* pointer) -{ - printf("Pointer: %p\n", pointer); -} - -int main() -{ - void* p1 = NULL; - void* p2 = nullptr; - - // Всё ОК (компилятор может выбрать функцию): - print(p1); - print(p2); - - // Тут неверно (компилятор не может выбрать перегруженную функцию, произойдёт ошибка): - print(NULL); - - // Тут всё OK: - print(nullptr); -} \ No newline at end of file diff --git a/seminar01_overload/classroom_tasks/code/04other/02default_arguments.cpp b/seminar01_overload/classroom_tasks/code/04other/02default_arguments.cpp deleted file mode 100644 index fcbc7bc..0000000 --- a/seminar01_overload/classroom_tasks/code/04other/02default_arguments.cpp +++ /dev/null @@ -1,42 +0,0 @@ -#include -using std::cout, std::endl; - -/* - В отличии от языка C, в C++ можно задавать значения по умолчанию - для аргументов функций - - Функцию printSquare можно вызвать с одним, двумя или тремя - параметрами. Аргументы width и height будут заданы аргументами по умолчанию. - Если передаваемых аргументов будет меньше трёх. -*/ - -void printSquare(char c, int width = 10, int height = 5) -{ - for (int i = 0; i < width; i++) - { - for (int j = 0; j < height; j++) - { - cout << c; - } - cout << endl; - } -} - -int main() -{ - printSquare('+', 6, 4); - printSquare('#', 15); - printSquare('O'); - - -} - - -/* - Задание: - - 1) Написать функцию: - void print(char str[], bool isCapitalized = false) - Которая будет просто печатать строку str, если isCapitalized = false, - а если isCapitalized = true, то будет печатать всю строку в верхнем регистре -*/ \ No newline at end of file diff --git a/seminar01_overload/homework/homework_overload.tex b/seminar01_overload/homework/homework_overload.tex deleted file mode 100644 index 74767fc..0000000 --- a/seminar01_overload/homework/homework_overload.tex +++ /dev/null @@ -1,160 +0,0 @@ -\documentclass{article} -\usepackage[utf8x]{inputenc} -\usepackage{ucs} -\usepackage{amsmath} -\usepackage{amsfonts} -\usepackage{marvosym} -\usepackage{wasysym} -\usepackage{upgreek} -\usepackage[english,russian]{babel} -\usepackage{graphicx} -\usepackage{float} -\usepackage{textcomp} -\usepackage{hyperref} -\usepackage{geometry} - \geometry{left=2cm} - \geometry{right=1.5cm} - \geometry{top=1cm} - \geometry{bottom=2cm} -\usepackage{tikz} -\usepackage{ccaption} -\usepackage{multicol} - -\usepackage{listings} -%\setlength{\columnsep}{1.5cm} -%\setlength{\columnseprule}{0.2pt} - -\usepackage{colortbl,graphicx,tikz} -\definecolor{X}{rgb}{.5,.5,.5} - -\title{ДЗ. Работа с изображениями в формате \texttt{.ppm}} -\date{} -\begin{document} -\pagenumbering{gobble} - -\lstset{ - language=C++, % choose the language of the code - basicstyle=\linespread{1.1}\ttfamily, - columns=fixed, - fontadjust=true, - basewidth=0.5em, - keywordstyle=\color{blue}\bfseries, - commentstyle=\color{gray}, - stringstyle=\ttfamily\color{orange!50!black}, - showstringspaces=false, - %numbers=false, % where to put the line-numbers - numbersep=5pt, - numberstyle=\tiny\color{black}, - numberfirstline=true, - stepnumber=1, % the step between two line-numbers. - numbersep=10pt, % how far the line-numbers are from the code - backgroundcolor=\color{white}, % choose the background color. You must add \usepackage{color} - showstringspaces=false, % underline spaces within strings - captionpos=b, % sets the caption-position to bottom - breaklines=true, % sets automatic line breaking - breakatwhitespace=true, % sets if automatic breaks should only happen at whitespace - xleftmargin=.2in, - extendedchars=\true, - keepspaces = true, -} -\lstset{literate=% - *{0}{{{\color{red!20!violet}0}}}1 - {1}{{{\color{red!20!violet}1}}}1 - {2}{{{\color{red!20!violet}2}}}1 - {3}{{{\color{red!20!violet}3}}}1 - {4}{{{\color{red!20!violet}4}}}1 - {5}{{{\color{red!20!violet}5}}}1 - {6}{{{\color{red!20!violet}6}}}1 - {7}{{{\color{red!20!violet}7}}}1 - {8}{{{\color{red!20!violet}8}}}1 - {9}{{{\color{red!20!violet}9}}}1 -} - - -\title{Семинар \#1: Ссылки и перегрузка операторов. Домашнее задание.\vspace{-5ex}}\date{}\maketitle -\subsection*{Пространство имён:} -\begin{itemize} -\item Создайте пространство имён по имени \texttt{myspace}. В этом пространстве имён создайте функцию \\ - \texttt{void print\_n\_times(char str[], int n = 10)}, которая будет печатать строку \texttt{str} \texttt{n} раз. Для печати используйте \texttt{std::cout} из библиотеки \texttt{iostream}. Вызовите эту функцию из \texttt{main}. -\end{itemize} - -\subsection*{Ссылки:} -\begin{itemize} -\item Напишите функцию \texttt{cube}, которая будет принимать одно число типа \texttt{int} и возводить его в куб. Используйте ссылки. Вызовите эту функцию из функции \texttt{main}. -\item Напишите функцию \texttt{void count\_letters(char str[], int\& n\_letters, int\& n\_digits, int\& n\_other)}, которая будет принимать на вход строку \texttt{str} и подсчитывать число букв и цифр в этой строке. Количество букв нужно записать в переменную \texttt{n\_letters}, количество цифр -- в переменную \texttt{n\_digits}, а количество остальных символов -- в переменную \texttt{n\_other}. Вызвать эту функцию из функции \texttt{main}. -\end{itemize} - -\subsection*{Перегрузка операций:} -В файлах \texttt{code/complex.h} и \texttt{code/complex.cpp} лежит реализация комплексного числа с перегруженными операторами. Используйте его в качестве примера для решения задач этого раздела: -\begin{itemize} -\item Создайте структуру \texttt{Vector3f} - вектор в трёхмерном пространстве с полями \texttt{x, y, z} типа \texttt{float} в качестве координат. Перегрузите следующие операторы для работы с вектором. Для передачи вектора в функции используте ссылки и, там где возможно, модификатор \texttt{const}. - \begin{itemize} - \item Сложение векторов (\texttt{+}) - \item Вычитание (\texttt{-}) - \item Умножение вектора на число типа \texttt{float} (число \texttt{*} вектор и вектор \texttt{*} число) - \item Деление вектора на число типа \texttt{float} (вектор \texttt{/} число) - \item Скалярное произведение (\texttt{*}) - \item Унарный \texttt{-} - \item Унарный \texttt{+} - \item Проверка на равенство \texttt{==} (должна возвращать тип \texttt{bool}) - \item Проверка на неравенство \texttt{!=} (должна возвращать тип \texttt{bool}) - \item Операторы \texttt{+=} и \texttt{-=} (вектор \texttt{+=} вектор) - \item Операторы \texttt{*=} и \texttt{/=} (вектор \texttt{*=} число) - \item Оператор вывода \texttt{ostream >{}>} вектор. Выводите вектор в виде \texttt{(x, y, z)}. - \item Оператор ввода \texttt{istream <{}<} вектор - \item Функция \texttt{float squared\_norm(const Vector3f\& a)}, которая вычисляет квадрат нормы вектора. - \item Функция \texttt{float norm(const Vector3f\& a)}, которая вычисляет норму вектора. - \item Функция \texttt{void normalize(Vector3f\& a)}, которая нормализует вектор \texttt{a}. - \end{itemize} -\item Поместите весь ваш код в отдельный файл \texttt{vector3f.h} и подключите к файлу \texttt{main.cpp}. -\item Протестируйте ваши функции: -\begin{lstlisting} -#include -#include "vector3f.h" - -using namespace std; - - -int main() { - Vector3f a = {1.0, 2.0, -2.0}; - Vector3f b = {4.0, -1.0, 3.0}; - cout << "a = " << a << endl << "b = " << b << endl; - cout << "a + b = " << a + b << endl; - cout << "-a = " << -a << endl; - cout << "Scalar product of a and b = " << a * b << endl; - a /= 5; - cout << "a after a /= 5;" << a << endl - normalize(b); - cout << "Normalized b:" << b << endl - a += b; - cout << "a after a+= b;" << a << endl; -} -\end{lstlisting} - -\end{itemize} -\subsection*{Задача об убегающей точке} -\begin{itemize} -\item Предположим, что у нас есть комплексная функция $f(z) = z^2$. Выберем некоторое комплексное число $z_0$ и будем проводить следующие итерации: -\begin{equation} -\label{fractalseq} -z_1 = f(z_0)\quad z_2 = f(z_1)\quad ...\quad z_{k+1} = f(z_k)\quad ... -\end{equation} -В зависимости от выбора точки $z_0$ эта последовательность либо разойдётся, либо останется в некоторой ограниченной области. Будем называть точку $z_0$ убегающей, если $z_k \rightarrow \infty$ при $k \rightarrow \infty$. Найдите область неубегания для функции $z^2$, т.е. множество всех начальных значений $z_0$, при которых последовательность (\ref{fractalseq}) остаётся ограниченной (это можно сделать в уме). \\ - -\item \textbf{Julia:} Для функции $f(z) = z^2$ эта область тривиальна, но всё становится сложней для функции вида $f(z) = z^2 + c$, где $c$ -- некоторое комплексное число. Численно найдите область неубегания для функций такого вида. Для этого создайте изображение размера 800x800, покрывающую область \texttt{[-2:2]x[-2:2]} на комплексной плоскости. Для каждой точки этой плоскости проведите $N \approx 20$ итераций и, в зависимости от результата, окрасьте пиксель в соответствующий цвет (цвет можно подобрать самим, он должен быть пропорционален значению $z_N$ - меняться от яркого если $z_N$ мало и до черного если $z_N$ большое). Используйте класс Complex и перегруженные операторы. Пример работы с изображениями в формате \texttt{ppm} можно посмотреть в файле \texttt{complex\_image.cpp}. Программа должна создавать файл \texttt{julia.ppm}. - -\begin{center} -\includegraphics[scale=0.7]{../images/complexplane.png} -\end{center} - -\item Нарисуте изображение для $c = -0.4 + 0.6i$;\quad $c = -0.70 - 0.38i$;\quad $c = -0.80 + 0.16i$\quad и\quad $c = 0.280 + 0.011i$. -\item Добавьте параметры командной строки: 2 вещественных числа, соответствующие комплексному числу $c$, и целое число итераций $N$. -\item \textbf{Mandelbrot:} Зафиксируем теперь $z_0 = 0$ и будем менять $c$. Численно найдите все параметры $c$, для которых точка $z_0$ не является убегающей. Для этого создайте изображение размера 800x800, покрывающую область \texttt{[-2:2]x[-2:2]} возможных значений $c$ на комплексной плоскости. Программа должна создавать файл \texttt{mandelbrot.ppm}. - -\item \textbf{Анимация:} Программа \texttt{complex\_movie.cpp} создаёт множество изображений и сохраняет их в папку \texttt{animation} (если у вас нет такой папки -- создайте её). Эти изображения представляют собой отдельные кадры будущей анимации. Чтобы их объединить в одно видео можно использовать программу ffmpeg (Нужно скачать тут: \href{https://www.ffmpeg.org/}{www.ffmpeg.org} и изменить переменную среды \texttt{PATH} в настройках Windows или Linux). После этого можно будет объединить все изображения в одно видео такой командой: -\begin{verbatim} -ffmpeg -r 60 -i animation/complex_%03d.ppm complex_movie.mp4 -\end{verbatim} -Создайте анимацию из изображений множеств Julia при $c$ линейно меняющемся от $(-1.5 - 0.5i)$ до $i$. -\end{itemize} -\end{document} \ No newline at end of file diff --git a/seminar01_overload/homework/homework_overload.pdf b/seminar01_overload/homework_overload.pdf similarity index 100% rename from seminar01_overload/homework/homework_overload.pdf rename to seminar01_overload/homework_overload.pdf diff --git a/seminar01_overload/images/complexplane.png b/seminar01_overload/images/complexplane.png deleted file mode 100644 index 729c878..0000000 Binary files a/seminar01_overload/images/complexplane.png and /dev/null differ diff --git a/seminar01_overload/images/complexplane.svg b/seminar01_overload/images/complexplane.svg deleted file mode 100644 index 1aa30f7..0000000 --- a/seminar01_overload/images/complexplane.svg +++ /dev/null @@ -1,490 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - z0 - z02 - - - - z1 - c - - z2 - - - z12 - - z3 - - - z22 - - 1 - - -1 - Re - Im - - - - diff --git a/seminar02_encapsulation/homework/code/0circle/circle.cpp b/seminar02_encapsulation/0circle/circle.cpp similarity index 100% rename from seminar02_encapsulation/homework/code/0circle/circle.cpp rename to seminar02_encapsulation/0circle/circle.cpp diff --git a/seminar02_encapsulation/homework/code/0circle/circle.h b/seminar02_encapsulation/0circle/circle.h similarity index 100% rename from seminar02_encapsulation/homework/code/0circle/circle.h rename to seminar02_encapsulation/0circle/circle.h diff --git a/seminar02_encapsulation/homework/code/0circle/main.cpp b/seminar02_encapsulation/0circle/main.cpp similarity index 100% rename from seminar02_encapsulation/homework/code/0circle/main.cpp rename to seminar02_encapsulation/0circle/main.cpp diff --git a/seminar02_encapsulation/homework/code/0circle/point.cpp b/seminar02_encapsulation/0circle/point.cpp similarity index 100% rename from seminar02_encapsulation/homework/code/0circle/point.cpp rename to seminar02_encapsulation/0circle/point.cpp diff --git a/seminar02_encapsulation/homework/code/0circle/point.h b/seminar02_encapsulation/0circle/point.h similarity index 100% rename from seminar02_encapsulation/homework/code/0circle/point.h rename to seminar02_encapsulation/0circle/point.h diff --git a/seminar02_encapsulation/homework/code/1number/main.cpp b/seminar02_encapsulation/1number/main.cpp similarity index 100% rename from seminar02_encapsulation/homework/code/1number/main.cpp rename to seminar02_encapsulation/1number/main.cpp diff --git a/seminar02_encapsulation/homework/code/1number/number.cpp b/seminar02_encapsulation/1number/number.cpp similarity index 100% rename from seminar02_encapsulation/homework/code/1number/number.cpp rename to seminar02_encapsulation/1number/number.cpp diff --git a/seminar02_encapsulation/homework/code/1number/number.h b/seminar02_encapsulation/1number/number.h similarity index 100% rename from seminar02_encapsulation/homework/code/1number/number.h rename to seminar02_encapsulation/1number/number.h diff --git a/seminar02_encapsulation/classroom_tasks/classroom_tasks_encapsulation.pdf b/seminar02_encapsulation/classroom_tasks/classroom_tasks_encapsulation.pdf deleted file mode 100644 index cddf46a..0000000 Binary files a/seminar02_encapsulation/classroom_tasks/classroom_tasks_encapsulation.pdf and /dev/null differ diff --git a/seminar02_encapsulation/classroom_tasks/classroom_tasks_encapsulation.tex b/seminar02_encapsulation/classroom_tasks/classroom_tasks_encapsulation.tex deleted file mode 100644 index 3b85f65..0000000 --- a/seminar02_encapsulation/classroom_tasks/classroom_tasks_encapsulation.tex +++ /dev/null @@ -1,405 +0,0 @@ -\documentclass{article} -\usepackage[utf8x]{inputenc} -\usepackage{ucs} -\usepackage{amsmath} -\usepackage{amsfonts} -\usepackage{marvosym} -\usepackage{wasysym} -\usepackage{upgreek} -\usepackage[english,russian]{babel} -\usepackage{graphicx} -\usepackage{float} -\usepackage{textcomp} -\usepackage{hyperref} -\usepackage{geometry} - \geometry{left=2cm} - \geometry{right=1.5cm} - \geometry{top=1cm} - \geometry{bottom=2cm} -\usepackage{tikz} -\usepackage{ccaption} -\usepackage{multicol} -\usepackage{fancyvrb} - -\usepackage{listings} -%\setlength{\columnsep}{1.5cm} -%\setlength{\columnseprule}{0.2pt} - -\usepackage{colortbl,graphicx,tikz} -\definecolor{X}{rgb}{.5,.5,.5} - -\title{ДЗ. Работа с изображениями в формате \texttt{.ppm}} -\date{} -\begin{document} -\pagenumbering{gobble} - -\lstset{ - language=C++, % choose the language of the code - basicstyle=\linespread{1.1}\ttfamily, - columns=fixed, - fontadjust=true, - basewidth=0.5em, - keywordstyle=\color{blue}\bfseries, - commentstyle=\color{gray}, - stringstyle=\ttfamily\color{orange!50!black}, - showstringspaces=false, - %numbers=false, % where to put the line-numbers - numbersep=5pt, - numberstyle=\tiny\color{black}, - numberfirstline=true, - stepnumber=1, % the step between two line-numbers. - numbersep=10pt, % how far the line-numbers are from the code - backgroundcolor=\color{white}, % choose the background color. You must add \usepackage{color} - showstringspaces=false, % underline spaces within strings - captionpos=b, % sets the caption-position to bottom - breaklines=true, % sets automatic line breaking - breakatwhitespace=true, % sets if automatic breaks should only happen at whitespace - xleftmargin=.2in, - extendedchars=\true, - keepspaces = true, -} -\lstset{literate=% - *{0}{{{\color{red!20!violet}0}}}1 - {1}{{{\color{red!20!violet}1}}}1 - {2}{{{\color{red!20!violet}2}}}1 - {3}{{{\color{red!20!violet}3}}}1 - {4}{{{\color{red!20!violet}4}}}1 - {5}{{{\color{red!20!violet}5}}}1 - {6}{{{\color{red!20!violet}6}}}1 - {7}{{{\color{red!20!violet}7}}}1 - {8}{{{\color{red!20!violet}8}}}1 - {9}{{{\color{red!20!violet}9}}}1 - {~} {$\sim$}{1} -} - - -\title{Семинар \#2: Инкапсуляция. Классные задачи.\vspace{-5ex}}\date{}\maketitle -\section*{Инкапсуляция} -Инкапсуляция -- это размещение в классе/структуре данных и функций, которые с ними работают. Структуру с методами можно называть классом. Переменные класса называются полями, а функции класса -- методами. -\begin{multicols}{2}\setlength{\columnseprule}{0.4pt} -\textbf{Без инкапсуляции:} -\begin{lstlisting} -#include -#include - -struct Point -{ - float x, y; -}; - -float norm(const Point& p) -{ - return std::sqrt(p.x*p.x + p.y*p.y); -} - -void normalize(Point& p) -{ - float pnorm = norm(p); - p.x /= pnorm; - p.y /= pnorm; -} - -Point operator+(const Point& l, - const Point& r) -{ - Point result = {l.x + r.x, l.y + r.y}; - return result; -} - -int main() -{ - Point p = {1, 2}; - normalize(p); - std::cout << p.x << " " - << p.y << std::endl; -} - -\end{lstlisting} - -\textbf{С инкапсуляцией:} -\begin{lstlisting} -#include -#include - -struct Point -{ - float x, y; - - float norm() const - { - return stdsqrt(x*x + y*y); - } - - void normalize() - { - float pnorm = norm(); - x /= pnorm; - y /= pnorm; - } - - Point operator+(const Point& r) const - { - Point result = {x + r.x, y + r.y}; - return result; - } -}; - -int main() -{ - Point p = {1, 2}; - p.normalize(); - std::cout << p.x << " " - << p.y << std::endl; -} -\end{lstlisting} -\end{multicols} -Обратите внимание на следующие моменты: -\begin{itemize} -\item[--] Методы имеют прямой доступ к полям \texttt{x} и \texttt{y}. Передавать саму структуру(или ссылку на неё) в методах не нужно. -\item[--] Вызов метода класса осуществляется с помощью оператора \texttt{.}(точка). -\item[--] Спецификатор \texttt{const} после объявления метода (например, \texttt{float norm() const}) означает, что этот метод не будет менять поля. -Желательно указывать этот спецификатор для всех методов, которые не изменяют объект. -\item[--] При перегрузке бинарных операций объектом является левый аргумент, а параметром функции -- правый. Т.е. \texttt{p + q} превратится в \texttt{p.operator+(q)}. -\end{itemize} - - -\subsection*{Модификаторы доступа \texttt{public} и \texttt{private}} -Модификаторы доступа служат для ограничения доступа к полям и методам класса. -\begin{itemize} -\item[--] \texttt{public} -- поля и методы могут использоваться где угодно -\item[--] \texttt{private} -- поля и методы могут использовать только методы этого класса и друзья (особые функции и классы, объявленные с использованием ключевого слова \texttt{friend}) -\end{itemize} - -\subsection*{Конструкторы} -Конструктор -- это специальный метод, который вызывается автоматически при создании экземпляра класса. -\begin{lstlisting} -struct Point { -private: - float x, y; -public: - // Конструктор: - Point(float ax, float ay) - { - x = ax; - y = ay; - } - // другие методы -}; - -int main() -{ - // Если несколько разных синтаксов создания экземпляра класса с вызовом конструктора: - Point a = Point(7, 3); - Point b(7, 3); - Point c = {7, 3}; - Point d {7, 3}; - // Все они делают одно и то же - создают переменную на стеке и вызывают конструктор - // В современном C++ предпочтительным является способ d -} -\end{lstlisting} -Особым видом конструктора является конструктор копирования: -\begin{lstlisting} -Point(const Point& p) -\end{lstlisting} -Он используется для создание нового экземпляра класса по уже имеющемуся экземпляру.\\ -\textbf{Задача 3:} Сделайте задание в файле \texttt{4point\_constructors.cpp} - -\subsection*{Ключевое слово \texttt{this} и оператор присваивания} -Ключевое слово \texttt{this} - это указатель на экземпляр класса, который можно использовать в методах этого класса.\\ -Оператор присваивания -- это просто перегруженный оператор \texttt{=}. Оператор присваивания должен вернуть ссылку на текущий объект, то есть \texttt{*this}.\\ - -Нужно различать оператор присваивания и вызов конструктора: -\begin{lstlisting} -Point a = Point(7, 3); // Конструктор ( оператор присваивания не вызывается ) -Point b = a; // Конструктор копирования ( оператор присваивания не вызывается ) -Point c; // Конструктор по умолчанию -c = a; // Оператор присваивания -\end{lstlisting} -Оператор присваивания должен возвращать ссылку на левый аргумент. - -\newpage -\section*{Создаём свой класс строки} -Строки в языке \texttt{C} представляют собой просто массивы с элементами типа \texttt{char}(однобайтовое число). Работать с такими строками не очень удобно. Нужно выделять и удалять необходимую память, следить за тем, чтобы строка помещалась в эту память на всём этапе выполнения программы, для работы со этими строками нужно использовать специальные функции из библиотеки \texttt{string.h}. Это всё может привести к ошибкам. В этом разделе мы создадим класс \texttt{String} -- класс строки, с которым удобнее и безопаснее работать, чем со строками в стиле \texttt{C}. Заготовка класса выглядит так (Это далеко не самая эффективная реализация строки, более правильная реализация создаётся в примерах кода): -\begin{lstlisting} -#include - -class String -{ -private: - - size_t size; - char* data; - -public: - - String(const char* str) - { - size = 0; - while (str[size]) - size++; - - data = (char*)malloc(sizeof(char) * (size + 1)); - - for (int i = 0; str[i]; i++) - data[i] = str[i]; - data[size] = '\0'; - } - - size_t getSize() const - { - return size; - } - - const char* cStr() const - { - return data; - } -}; - -int main() -{ - String a = "Elephant"; -} -\end{lstlisting} - -Схематично это можно представить следующим образом: -\begin{center} -\includegraphics[scale=0.86]{../images/string_base.png} -\end{center} - -\newpage -\subsection*{Деструктор} -В коде выше выделяется память для массива \texttt{data}. Эта память выделяется при вызове конструктора (то есть при создании объекта). Однако она нигде не освобождается. Освободить её вручную мы не можем, так как поле \texttt{data} является приватным и это бы противоречило принципу сокрытия данных. Эта память должна освобождаться автоматически при удалении объекта. -\begin{lstlisting} -~ String() -{ - free(data); -} -\end{lstlisting} - -\subsection*{Перегруженные операторы класса \texttt{String}} -\begin{itemize} -\item \textbf{Оператор сложения:} \texttt{String operator+(const String\& right) const} \\ -Этот оператор должен создавать новый экземпляр, задавать его поля (в частности придётся выделить память под строку-сумму) и возвращать этот экземпляр. - -\item \textbf{Оператор присваивания сложения:} \texttt{String\& operator+=(const String\& right)}\\ -Этот оператор не должен создавать новый экземпляр. Он должен изменять левый операнд (т. е. сам объект), и возвращать ссылку на этот объект (т. е. \texttt{*this}). - -\item \textbf{Оператор присваивания:} \texttt{String\& operator=(const String\& right)}\\ -Этот оператор не должен создавать новый экземпляр. Он должен изменять левый операнд (т. е. сам объект), так чтобы он стал идентичен правому. Если размеры строк не совпадают, то в данной реализации строки вам придётся удалить память левой строки и снова выделить память нужного размера. При этом нужно отдельно рассмотреть случай когда левый и правый операнд это один и тот же объект. -\begin{lstlisting} -String a {"Cat"}; -a = a; -\end{lstlisting} -Конечно, в этом случае ничего удалять не нужно. - -\item \textbf{Оператор сравнения:} \texttt{bool operator==(const String\& right) const}\\ -Этот оператор должен сравнивать строки (массивы \texttt{data}) и возвращать \texttt{true} или \texttt{false}. - -\item \textbf{Оператор индексации:} \texttt{char\& operator[](unsigned int i)}\\ -Этот оператор должен возвращать ссылку на \texttt{i}-ый символ строки. - -\item \textbf{Индексация с проверкой на выход за границы:} \texttt{char\& at(unsigned int i)}\\ -Этот метод должен проверять, что индекс \texttt{i} не выходит за границы диапазона и, если это так, возвращать ссылку на \texttt{i}-ый символ строки. Иначе, этот метод должен печатать сообщение об ошибке и завершать программу. -\end{itemize} - -\newpage -\section*{Раздельная компиляция класса} -Методы можно вынести из определения класса следующим образом: -\begin{multicols}{2}\setlength{\columnseprule}{0.4pt} -\textbf{Определение методов в теле класса:} -\begin{lstlisting} -#include -#include - - -struct Point -{ - float x, y; - - float norm() const - { - return std::sqrt(x *x + y * y); - } - - void normalize() - { - float pnorm = norm(); - x /= pnorm; - y /= pnorm; - } - - Point operator+(const Point& r) const - { - Point result = {x + r.x, y + r.y}; - return result; - } -}; - - - - - -int main() -{ - Point p = {1, 2}; - p.normalize(); - std::cout << p.x << " " - << p.y << std::endl; -} -\end{lstlisting} -\vfill\null -\columnbreak - -\textbf{Определение методов вне тела класса:} -\begin{lstlisting} -#include -#include - -struct Point -{ - float x, y; - - float norm() const; - void normalize(); - Point operator+(const Point& r) const; -}; - -float Point::norm() const -{ - return sqrt(x*x + y*y); -} - -void Point::normalize() -{ - float pnorm = norm(); - x /= pnorm; - y /= pnorm; -} - -Point Point::operator+(const Point& r) const -{ - Point result = {x + r.x, y + r.y}; - return result; -} - -int main() -{ - Point p = {1, 2}; - p.normalize(); - std::cout << p.x << " " - << p.y << std::endl; -} -\end{lstlisting} -\end{multicols} - -Теперь эти методы можно скомпилировать отдельно. Для этого их нужно вынести в отдельный компилируемый файл \texttt{point.cpp}, а определение класса в отдельный файл \texttt{point.h}. Так называемый заголовочный файл \texttt{point.h} нужен, так как определение класса нужно и файле \texttt{point.cpp} и в файле \texttt{main.cpp}. Для компиляции используем: -\begin{verbatim} -g++ main.cpp point.cpp -\end{verbatim} - -\begin{center} -\includegraphics[scale=0.65]{../images/sepcompilation.png} -\end{center} - -\end{document} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/0book/00oop.cpp b/seminar02_encapsulation/classroom_tasks/code/0book/00oop.cpp deleted file mode 100644 index e980ef0..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/0book/00oop.cpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - Объектно-ориентированное программирование (ООП) основано на представлении программы в виде совокупности взаимодействующих объектов - - Основные принципы ООП: абстракция, инкапсуляция, наследование и полиморфизм - - - Абстракция: использование только тех характеристик объекта, которые с достаточной точностью представляют его в данной системе. - - В каком-то смысле обычные структуры из языка C являются примером абстракции - - struct book - { - char title[100]; - float price; - int pages; - }; - - Для описание книги в коде мы используем лишь некоторое её характеристики, достаточные для нашей задачи - - - - Инкапсуляция: связывание данных некоторого абстрактного объекта и функций для работы с ним - Тесно связано с инкапсуляцией такое понятие как сокрытие - - Сокрытие: разделение данных и функций абстрактного объекта на открытые (видимые извне) и скрытые (видимые только внутри самого объекта) - - - - Наследование и Полиморфизм будут пройдены позже в курсе -*/ - - - -int main(){} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/0book/01book.c b/seminar02_encapsulation/classroom_tasks/code/0book/01book.c deleted file mode 100644 index 592e979..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/0book/01book.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - Хоть язык C и не является объектно-ориентированным, некоторые зачатки подходов ООП в нём тоже есть - Например, структуры языка C являются примером Абстракции - - Для работы со структурами мы обычно писали функции так, что каждая из этих функций принимает на вход первым аргументом указатель на наш объект. - Такой подход НЕ является примером Инкапсуляции, так как структура и функции для работы с ней являются независимыми друг от друга. - При желании или по ошибке можно первым аргументом в эти функции передать вообще объект другого типа. - - - - Эта программа написана на языке C, для компиляции используйте gcc: - gcc 00book.c - - Функции в этом примере делают следующее: - - make_discount сделать скидку на книгу, но цена на книгу не может упасть ниже 0. - print_book напечатать информацию о книге на экран -*/ - -#include - - -struct book -{ - char title[100]; - float price; - int pages; -}; -typedef struct book Book; - - -void make_discount(Book* pb, int discount) -{ - if (pb->price > discount) - pb->price -= discount; - else - pb->price = 0; -} - -void print_book(const Book* pb) -{ - printf("%s, price = %.2f, pages = %i\n", pb->title, pb->price, pb->pages); -} - - - -int main() -{ - Book b = {"War and Peace", 1700, 900}; - - print_book(&b); - make_discount(&b, 500); - print_book(&b); -} diff --git a/seminar02_encapsulation/classroom_tasks/code/0book/02book.cpp b/seminar02_encapsulation/classroom_tasks/code/0book/02book.cpp deleted file mode 100644 index 76c53c1..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/0book/02book.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - Эта программа написана на языке C++, для компиляции используйте g++: - g++ 01book.cpp - - В языке C++ появились ссылки, которые могут немного упростить код из предыдущего файла - - Тем не менее, структура Book и функции для работы с ней всё ещё являются независимыми друг от друга. - То есть тут тоже нет Инкапсуляции. -*/ - -#include - - -struct Book -{ - char title[100]; - float price; - int pages; -}; - - -void makeDiscount(Book& b, int discount) -{ - if (b.price > discount) - b.price -= discount; - else - b.price = 0; -} - -void printBook(const Book& b) -{ - std::cout << b.title << ", price = " << b.price << ", pages = " << b.pages << std::endl; -} - - - -int main() -{ - Book b = {"War and Peace", 1700, 900}; - - printBook(b); - makeDiscount(b, 500); - printBook(b); -} diff --git a/seminar02_encapsulation/classroom_tasks/code/0book/03book_encapsulation.cpp b/seminar02_encapsulation/classroom_tasks/code/0book/03book_encapsulation.cpp deleted file mode 100644 index 6b3cfce..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/0book/03book_encapsulation.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - Инкапсуляция - это объединение данных и функций для работы с ними - - Объекты-данные, составляющие наш объект, называются полями - Функции для работы с этими данными называются методами - То есть у структуры Book из этого примера есть 3 поля (title, price и pages) и 2 метода (makeDiscount и print) - - - Сравните код в этом файле с кодом из предыдущего файла и обратите внимание на следующие моменты: - - 1) Функции для работы со структурой сейчас объявляются внутри структуры. - Получается методы как-бы принадлежат самой структуре - Это делает невозможным использование этих функций (случайно или намерено) для работы с объектами других типов. - - 2) Вызов методов осуществляется с помощью точки, то есть такой вызов из прошлого файла: - makeDiscount(b, 500); - заменился на такой: - b.makeDiscount(500); - - То есть объект как бы сам вызывает функцию для работы со своими данными, а не передаётся первым аргументом в функцию. - - - 3) Методы "знают" о том объекте, который их вызвал - - Например, в методе makeDiscount используется поле price без указания объекта, которому принадлежит это поле - Но метод сам "знает" какой объект его вызвал, поэтому если его вызывает объект a вот так: - a.makeDiscount(500); - то в этом случае метод использует поле price объекта a - - - 4) Константный метод не меняет полей вызывающего объекта. - Чтобы указать, что метод является константным нужно написать const в конце объявления метода - - В предыдущем файле при передаче по константной ссылке передаваемый объект не мог измениться внутри функции - void printBook(const Book& b) -> printBook(b) не изменит b - - Аналог этого для константного метода: - void print() const -> b.print() не изменит b - Следовательно, внутри константного метода нельзя менять поля объекта - -*/ - -#include - -struct Book -{ - char title[100]; - float price; - int pages; - - void makeDiscount(int discount) - { - if (price > discount) - price -= discount; - else - price = 0; - } - - void print() const - { - std::cout << title << ", price = " << price << ", pages = " << pages << std::endl; - } -}; - - - -int main() -{ - Book a = {"War and Peace", 1700, 900}; - Book b = {"The Master and Margarita", 600, 400}; - - a.print(); - a.makeDiscount(500); - a.print(); -} - -/* - Задачи: - - 1) Напечатайте книгу b - - 2) Сделайте скидку для книги b в 1000 рублей и напечатайте её ещё раз - - 3) Напишите метод void setPrice(float newPrice) который будет задавать новую цену книги - Вызовите этот метод для книги b и установите её цену в 1000 рублей. Напечатайте книгу ещё раз. - - 4) Попробуйте изменить поле внутри константного метода print, к какой ошибке это приведёт? - - 5) Можно ли вызвать метод makeDiscount из константного метода? - -*/ diff --git a/seminar02_encapsulation/classroom_tasks/code/0book/04problem_movie.cpp b/seminar02_encapsulation/classroom_tasks/code/0book/04problem_movie.cpp deleted file mode 100644 index cf02e21..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/0book/04problem_movie.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - Задачи: Представлена структура Movie, описывающая фильм на Кинопоиске - title - название фильма - releaseYear - год выхода - numVotes - число оценок этого фильма на Кинопоиске - rating - рейтинт фильма на Кинопоиске - - - - 1) Напишите метод setReleaseYear, который будет принимать число и устанавливать новый год выхода фильма, - равный этому числу. Этот метод не должен ничего возвращать. - При этом, минимальный год выхода фильма должен быть 1900. При попытке установить меньший год выхода, метод - всё-равно должен устанавливать год, равный 1900. - - 2) Установите год выхода фильма a на 1998, используя метод setReleaseYear. Напечатайте фильм. - Попробуйте установить год выхода, равный 1600 Напечатайте фильм. - - - 3) Напишите метод void addVote(float x), который будет имитировать проставление оценки x фильму одним пользователем - numVotes должен увеличиться на 1 и rating должен тоже изменится по формуле - - новыйРейтинг = (старыйРейтиг * староеКоличествоГолосов + x) / (староеКоличествоГолосов + 1) - - 4) У данного фильма 4 голоса со средней оценкой 8.0. Добавьте ещё одну оценку, равную 10.0. - Напечатайте фильм, новый рейтинг фильма должен быть равен 8.4. - -*/ - -#include -using std::cout, std::endl; - - -struct Movie -{ - char title[100]; - int releaseYear; - int numVotes; - float rating; - - - void print() const - { - cout << title << ", releaseYear = " << releaseYear << ", rating = " << rating - << " (" << numVotes << " votes)" << endl; - } -}; - - - - -int main() -{ - Movie a = {"Dark City", 2000, 4, 8.0}; - a.print(); -} - diff --git a/seminar02_encapsulation/classroom_tasks/code/0book/04problem_movie_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/0book/04problem_movie_solution.cpp deleted file mode 100644 index 975b00b..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/0book/04problem_movie_solution.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include -using std::cout, std::endl; - - -struct Movie -{ - char title[100]; - int releaseYear; - int numVotes; - float rating; - - void setReleaseYear(int year) - { - releaseYear = year; - if (releaseYear < 1900) - releaseYear = 1900; - } - - void addVote(int x) - { - rating = (rating * numVotes + x) / (numVotes + 1); - numVotes += 1; - } - - void print() const - { - cout << title << ", releaseYear = " << releaseYear << ", rating = " << rating - << " (" << numVotes << " votes)" << endl; - } -}; - - - - -int main() -{ - Movie a = {"Dark City", 2000, 4, 8.0}; - a.print(); - - a.setReleaseYear(1998); - a.print(); - - a.setReleaseYear(1600); - a.print(); - - a.addVote(10.0); - a.print(); -} - diff --git a/seminar02_encapsulation/classroom_tasks/code/0book/05this_pointer.cpp b/seminar02_encapsulation/classroom_tasks/code/0book/05this_pointer.cpp deleted file mode 100644 index c3f4bd7..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/0book/05this_pointer.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - Ключевое слово this - - Используя указатель this внутри структуры, можно узнать адрес объекта. - Например, если метод был вызван таким образом: - a.printThis(); - то внутри метода this будет означать адрес объекта a - - С помощью этого указателя можно доступаться до полей класса. - Например, title и this->title это одно и то же внутри методов структуры. - - this можно использовать, если имя аргумента метода совпадает с одним из полей, как, например, в методе setPrice - Внутри метода setPrice поле price перекрывается аргументом price. Но можно всё-равно доступиться до поля price, используя указатель this -*/ - -#include -using std::cout, std::endl; - - -struct Book -{ - char title[100]; - float price; - int pages; - - void printThis() const - { - cout << this << endl; - } - - void printTitle() const - { - cout << title << endl; - cout << this->title << endl; - } - - void setPrice(float price) - { - this->price = price; - } -}; - - -int main() -{ - Book a = {"War and Peace", 1700, 900}; - - cout << &a << endl; - a.printThis(); - - a.printTitle(); -} - diff --git a/seminar02_encapsulation/classroom_tasks/code/0book/06constructor.cpp b/seminar02_encapsulation/classroom_tasks/code/0book/06constructor.cpp deleted file mode 100644 index 073fd86..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/0book/06constructor.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - Конструктор - - Конструктор - это специальный метод, который вызывается при создании объекта - - Конструктор Book(const char aTitle[], float aPrice, int aPages) принимает три аргумента и задаёт - этими аргументами поля класса, а также печатает на экран слово Constructor. - - Конструктор вызывается в строке Book a = Book("War and Peace", 1700, 900). - В этом примере конструктор делает то же самое, что и обычная инициализация структуры: Book a = {"War and Peace", 1700, 900}; - Преимущество конструктора по сравнению с обычной инициализации структур состоит в том, что программист может сам задать то, - что будет происходить при создании объекта. - - - Напоминание: - Функция strcpy из библиотеки string.h языка C принимает на вход 2 строки и просто копирует - содержимое второй строки в первую строку. - -*/ - -#include -#include -#include -using std::cout, std::endl; - - -struct Book -{ - char title[100]; - float price; - int pages; - - Book(const char aTitle[], float aPrice, int aPages) - { - cout << "Constructor" << endl; - strcpy(title, aTitle); - price = aPrice; - pages = aPages; - } - - - void print() const - { - std::cout << title << ", price = " << price << ", pages = " << pages << std::endl; - } -}; - - - -int main() -{ - Book a = Book("War and Peace", 1700, 900); - a.print(); - - Book b = Book("The Great Gatsby", 800, -600); - b.print(); - -} - - -/* - Задачи: - - 1) Предположим, что программист, работая с наши классом Book, ошибся в конструкторе и установил у книги отрицательное количество страниц. - - Измените конструктор таким образом, чтобы программа не создавала объект с отрицательным числом страниц. - Вместо этого она должна писать сообщение об ошибке и выходить из программы. - Для выхода из программы можно использовать функцию std::exit(1) из библиотеки - - - 2) Конструкторы можно перегружать также, как и обычные функции и методы. - Добавьте новый конструктор, который не будет принимать никаких аргументов и будет создавать объект с полями равными - title: "Default" price: 0 pages: 0 - Вызовите этот конструктор из main - - Конструктор, который не принимает аргументов, называется конструктором по умолчанию. - - - - 3) Конструкторы можно перегружать также, как и обычные функции и методы. - Добавьте новый конструктор, который будет принимать объект типа Book (по константной ссылке) - и будет задавать поля текущего объекта, используя поля аргумента - Вызовите этот конструктор из main - - Конструктор, который создаёт объект, используя объект такого-же типа, называется конструктором копирования. -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/0book/06constructor_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/0book/06constructor_solution.cpp deleted file mode 100644 index 7d423e9..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/0book/06constructor_solution.cpp +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include -#include -#include -using std::cout, std::endl; - - -struct Book -{ - char title[100]; - float price; - int pages; - - Book(const char aTitle[], float aPrice, int aPages) - { - cout << "Constructor" << endl; - strcpy(title, aTitle); - price = aPrice; - pages = aPages; - - if (pages < 0) - { - cout << "Error! Number of pages can't be negative!" << endl; - std::exit(1); - } - } - - Book() - { - cout << "Default Construtor" << endl; - strcpy(title, "Default"); - price = 0; - pages = 0; - } - - - Book(const Book& b) - { - cout << "Copy Construtor" << endl; - strcpy(title, b.title); - price = b.price; - pages = b.pages; - } - - - - void print() const - { - cout << title << ", price = " << price << ", pages = " << pages << endl << endl; - } -}; - - - -int main() -{ - Book a = Book("War and Peace", 1700, 900); - a.print(); - - Book b = Book(); - b.print(); - - Book c = Book(a); - c.print(); - - Book d = Book("The Great Gatsby", 800, -600); - d.print(); - -} diff --git a/seminar02_encapsulation/classroom_tasks/code/0book/07public_private.cpp b/seminar02_encapsulation/classroom_tasks/code/0book/07public_private.cpp deleted file mode 100644 index 7c0209f..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/0book/07public_private.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - Сокрытие данных - это разделение данных и функций абстрактного объекта на открытые (видимые извне) и скрытые (видимые только внутри самого объекта) - В языке C++ это реализуется с помощью модификаторов доступа public и private - - Все поля и методы объявленные в секции public называются публичными и могут быть доступны извне структуры - Все поля и методы объявленные в секции private называются приватными и не могут быть доступны извне структуры - Приватные поля и методы могут быть доступны только в методах самого структуры (а также в друзьях, но об этом позже) - - - Назначение сокрытия данных заключается в том, чтобы объекты нельзя было 'поломать' извне - 'Поломать' тут означает задать поля объекта бессмысленным образом - - Например, в нашем примере мы бы могли поломать объект просто сделав поля price или pages отрицательными - a.pages = -100; - но благодаря тому, что поле pages является приватным, это сделать нельзя. - - - Учитывая проверку в конструкторе, получается, что поля pages и price в принципе никогда не смогут стать отрицательными. - Таким образом мы уберегли себя от возникновения ошибок при неправильном задании полей структуры. -*/ - -#include -#include -#include -#include -using std::cout, std::endl; - - -struct Book -{ -private: - char title[100]; - float price; - int pages; - -public: - Book(const char aTitle[], float aPrice, int aPages) - { - if (aPages < 0 || aPrice < 0 || strlen(aTitle) >= 100) - { - cout << "Error while creating Book!" << endl; - std::exit(1); - } - - strcpy(title, aTitle); - price = aPrice; - pages = aPages; - } - - - void print() const - { - cout << title << ", price = " << price << ", pages = " << pages << endl; - } -}; - - - -int main() -{ - Book a = Book("War and Peace", 1700, 900); - a.print(); - - a.pages = -100; -} diff --git a/seminar02_encapsulation/classroom_tasks/code/0book/08constructor_calls.cpp b/seminar02_encapsulation/classroom_tasks/code/0book/08constructor_calls.cpp deleted file mode 100644 index edc10b4..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/0book/08constructor_calls.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - Синтаксис инициализации с помощью коструктора - - Язык C++ имеет очень длинную историю и на её протяжении в язык добавлялись новые возможности - В итоге в языке часто можно сделать одно и то же разными методами. - - В частности, вызвать конструктор можно 5-ю разными способами. - В этой программе строки для создания книг a, b, c, d, e делают одно и то же, несмотря, что имеют разный синтаксис -*/ - -#include -#include -#include -#include -using std::cout, std::endl; - - -struct Book -{ -private: - char title[100]; - float price; - int pages; - -public: - Book(const char aTitle[], float aPrice, int aPages) - { - cout << "Constructor" << endl; - strcpy(title, aTitle); - price = aPrice; - pages = aPages; - } - - - void print() const - { - cout << title << ", price = " << price << ", pages = " << pages << endl; - } -}; - - - -int main() -{ - Book a = Book("War and Peace", 1000, 500); - - Book b("War and Peace", 1000, 500); - - Book c = {"War and Peace", 1000, 500}; - - Book d = Book{"War and Peace", 1000, 500}; - - Book e {"War and Peace", 1000, 500}; - - a.print(); - b.print(); - c.print(); - d.print(); - e.print(); -} - -/* - Задача: - - 1) Добавьте к классу конструктор по умолчанию: - - Book() - { - cout << "Default Constructor" << endl; - strcpy(title, "default"); - price = 0; - pages = 0; - } - - Создайте с помощью этого конструктора 5 книг, вызвав его 5-ю разными способами - -*/ diff --git a/seminar02_encapsulation/classroom_tasks/code/0book/08constructor_calls_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/0book/08constructor_calls_solution.cpp deleted file mode 100644 index 8ce1003..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/0book/08constructor_calls_solution.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include -#include -#include -using std::cout, std::endl; - - -struct Book -{ -private: - char title[100]; - float price; - int pages; - -public: - Book(const char aTitle[], float aPrice, int aPages) - { - cout << "Constructor" << endl; - strcpy(title, aTitle); - price = aPrice; - pages = aPages; - } - - Book() - { - cout << "Default Constructor" << endl; - strcpy(title, "default"); - price = 0; - pages = 0; - } - - - void print() const - { - cout << title << ", price = " << price << ", pages = " << pages << endl; - } -}; - - - -int main() -{ - Book a = Book(); - - // Book b(); // этот способ не работает, так как его невозможно отличить от объявления функции (зато добавился способ f) - - Book c = {}; - - Book d = Book{}; - - Book e {}; - - Book f; // в отличии от переменных базовых типов, тут произойдёт инициализация (конструктором по умолчанию) - - a.print(); - c.print(); - d.print(); - e.print(); - f.print(); -} - - diff --git a/seminar02_encapsulation/classroom_tasks/code/0book/09class.cpp b/seminar02_encapsulation/classroom_tasks/code/0book/09class.cpp deleted file mode 100644 index d1b1701..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/0book/09class.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* - Классы. Ключевое слово class. - - На самом деле классы мы уже прошли. Структуры с методоми из предыдущих файлов это и есть классы. - Для объявления класса может использоваться ключевое слово class. - - Разница между этими ключевым словами минимальна - - при использовании struct все поля и методы по умолчанию публичны - - при использовании class все поля и методы по умолчанию приватны - Но, так как мы указываем private и public для всех членов, то разницы нет вообще. -*/ - -#include -#include -#include -#include -using std::cout, std::endl; - -class Book -{ -private: - char title[100]; - float price; - int pages; - -public: - Book(const char aTitle[], float aPrice, int aPages) - { - if (aPages < 0 || aPrice < 0 || strlen(aTitle) >= 100) - { - cout << "Error while creating Book!" << endl; - std::exit(1); - } - - strcpy(title, aTitle); - price = aPrice; - pages = aPages; - } - - - void print() const - { - cout << title << ", price = " << price << ", pages = " << pages << endl; - } -}; - - - -int main() -{ - Book a = Book("War and Peace", 1700, 900); - a.print(); -} diff --git a/seminar02_encapsulation/classroom_tasks/code/0book/10m.cpp b/seminar02_encapsulation/classroom_tasks/code/0book/10m.cpp deleted file mode 100644 index 8966466..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/0book/10m.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - Некоторые замечания по оформлению - - 1) Как правило в классе сначала описываются публичные методы, а потом приватные - Так делают потому что если другой программист захочет воспользоваться вашим классом, - то его будет в первую очередь будет интересовать что ваш класс может делать - и уже потом его будет интересовать строение класса. - - - 2) Приватные поля класса желательно называть так, чтобы их можно было отличить от обычных переменных - Это может сильно упростить понимание при написании/использовании больших програм и библиотек - В данном курсе мы будем называть приватные поля начиная с буквы m - Например, mTitle вместо title -*/ - -#include -#include -#include -#include -using std::cout, std::endl; - - -class Book -{ -public: - Book(const char title[], float price, int pages) - { - if (pages < 0 || price < 0 || strlen(title) >= 100) - { - cout << "Error while creating Book!" << endl; - std::exit(1); - } - - strcpy(mTitle, title); - mPrice = price; - mPages = pages; - } - - void print() const - { - cout << mTitle << ", price = " << mPrice << ", pages = " << mPages << endl; - } - -private: - char mTitle[100]; - float mPrice; - int mPages; -}; - - - -int main() -{ - Book a = Book("War and Peace", 1700, 900); - a.print(); -} diff --git a/seminar02_encapsulation/classroom_tasks/code/1point/00point.c b/seminar02_encapsulation/classroom_tasks/code/1point/00point.c deleted file mode 100644 index 9469d8f..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/1point/00point.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - Это программа на языке C, для компиляции: - gcc 00point.c - ./a.out - - Опишем структуру точки в двумерном пространстве на языке C - - Точка задаётся двумя координатами x и y - Так как эта структура имеет очень маленький размер (всего 8 байт), то в функции - её можно передавать по значению, а не по константному указателю. -*/ - -#include -#include - -struct point -{ - float x, y; -}; -typedef struct point Point; - - -void point_print(Point a) -{ - printf("(%.2f, %.2f)\n", a.x, a.y); -} - - -int main() -{ - Point a = {7.2, 3.1}; - Point b = {-4.6, 2.4}; - - point_print(a); - point_print(b); -} - -/* - Задачи: - - 1) Напишите функцию point_add, - которая будет принимать две точки и возвращать их сумму - - 2) Напишите функцию point_norm, - которая будет принимать точку и возвращать расстояние до этой точки от начала координат - Будем называть расстояние от точки до начала координат нормой точки - Для вычисления корня числа можно использовать функцию sqrt из math.h - - 3) Напишите функцию point_mult, - которая будет принимать на вход точку и число k типа float и возвращать точку, координаты которой - равны координатам изначальной точки, умноженные на число k - - 4) Напишите функцию point_normalize, - которая будет принимать точку по указателю и делить координаты точки на норму точки - Эта функция не должна ничего возвращать -*/ diff --git a/seminar02_encapsulation/classroom_tasks/code/1point/00point_solution.c b/seminar02_encapsulation/classroom_tasks/code/1point/00point_solution.c deleted file mode 100644 index 6533acb..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/1point/00point_solution.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - Это программа на языке C, для компиляции: - gcc 00point_solution.c - ./a.out -*/ - -#include -#include - - -struct point -{ - float x, y; -}; -typedef struct point Point; - - -void point_print(Point a) -{ - printf("(%.2f, %.2f)\n", a.x, a.y); -} - -Point point_add(Point a, Point b) -{ - Point result = {a.x + b.x, a.y + b.y}; - return result; -} - -float point_norm(Point a) -{ - return sqrtf(a.x * a.x + a.y * a.y); -} - -Point point_mult(Point a, float k) -{ - Point result = {k * a.x, k * a.y}; - return result; -} - -void point_normalize(Point* pa) -{ - float norm = point_norm(*pa); - pa->x /= norm; - pa->y /= norm; -} - - -int main() -{ - Point a = {7.2, 3.1}; - Point b = {-4.6, 2.4}; - - point_print(a); - point_print(b); - - Point c = point_add(a, b); - point_print(c); - - point_print(point_mult(c, 1.5f)); - - point_normalize(&c); - point_print(c); -} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/1point/01point.cpp b/seminar02_encapsulation/classroom_tasks/code/1point/01point.cpp deleted file mode 100644 index 62d5ae0..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/1point/01point.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - Это программа на языке C++, для компиляции: - g++ 01point.cpp - - Та же самая точка, но на языке C++ - - В этом файле была видоизменена программа из предыдущего файла. - Были использованы перегруженные операторы для более удобного сложения и умножения точек. - Также была использована ссылка вместо указателя в функции pointNormalize. -*/ - -#include -#include -#include -using std::cout, std::endl; - - -struct Point -{ - float x, y; -}; - -void pointPrint(Point a) -{ - cout << std::setprecision(2) << "(" << a.x << ", " << a.y << ")" << endl; -} - -Point operator+(Point a, Point b) -{ - Point result = {a.x + b.x, a.y + b.y}; - return result; -} - -float pointNorm(Point a) -{ - return std::sqrt(a.x * a.x + a.y * a.y); -} - -Point operator*(Point a, float k) -{ - Point result = {k * a.x, k * a.y}; - return result; -} - -void pointNormalize(Point& a) -{ - float norm = pointNorm(a); - a.x /= norm; - a.y /= norm; -} - - - - -int main() -{ - Point a = {7.2, 3.1}; - Point b = {-4.6, 2.4}; - - pointPrint(a); - pointPrint(b); - - Point c = a + b; - pointPrint(c); - - pointPrint(c * 1.5f); - - pointNormalize(c); - pointPrint(c); -} - - - - -/* - Задача: - - 1) Инкапсулируйте функции operator+, pointNorm, operator* и pointNormalize - Их нужно сделать методами, то есть положить внутрь структуры Point - Не забудьте сделать соответствующие методы константными - - 2) Можно сделать то же самое с функцией printPoint, а можно поступить по-другому - и перегрузить оператор << для типов std::ostream и Point -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/1point/01point_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/1point/01point_solution.cpp deleted file mode 100644 index 1cbfbbe..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/1point/01point_solution.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - Обратите внимание на следующие моменты в этом решении: - - 1) При переносе функций внутрь класса у них стало на 1 аргумент меньше - Просто потому что все методы неявно принимают вызывающий их объект - - Например, если a это точка, то при вызове: - a.norm() - - метод norm 'знает', что его вызвала имено точка a и может доступаться до её полей x и y - - - 2) Перегруженные операторы тоже могут быть методами - При этом оператор преобразуется следующим образом: - - a @ b -> a.operator@(b) - где на месте @ может быть любой бинарный оператор - - Например, сложение преобразуется так: - a + b -> a.operator+(b) - - Обратите внимание, что перегруженный оператор может стать методом только первого аргумента - - - 3) Перегрузка оператора << для типов std::ostream и Point - Для более удобного вывода на экран можно перегрузить этот оператор - - Когда компилятор встретит выражение cout << a где cout имеет тип std::ostream, а имеет тип Point - то он вызовет эту функцию. - Эта функция должна вызывать ссылку на cout так как результатом cout << a тоже должен быть cout - чтобы мы могли выводить цепочкой, например так: cout << a << b << endl -*/ - -#include -#include -#include -using std::cout, std::endl; - - -struct Point -{ - float x, y; - - Point operator+(Point b) const - { - Point result = {x + b.x, y + b.y}; - return result; - } - - float norm() const - { - return std::sqrt(x * x + y * y); - } - - Point operator*(float k) const - { - Point result = {k * x, k * y}; - return result; - } - - void normalize() - { - float normv = norm(); - x /= normv; - y /= normv; - } -}; - -std::ostream& operator<<(std::ostream& out, Point a) -{ - out << std::setprecision(2) << "(" << a.x << ", " << a.y << ")"; - return out; -} - - - - -int main() -{ - Point a = {7.2, 3.1}; - Point b = {-4.6, 2.4}; - - cout << a << endl; - cout << b << endl; - - Point c = a + b; - cout << c << endl; - - cout << c * 1.5f << endl; - - c.normalize(); - cout << c << endl; -} - - - - diff --git a/seminar02_encapsulation/classroom_tasks/code/1point/02operator_order.cpp b/seminar02_encapsulation/classroom_tasks/code/1point/02operator_order.cpp deleted file mode 100644 index 5a5798f..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/1point/02operator_order.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include -#include -#include -using std::cout, std::endl; - - -struct Point -{ - float x, y; - - Point operator*(float k) const - { - Point result = {k * x, k * y}; - return result; - } - -}; - -std::ostream& operator<<(std::ostream& out, Point a) -{ - out << std::setprecision(2) << "(" << a.x << ", " << a.y << ")"; - return out; -} - - -int main() -{ - Point a = {2.1, 1.5}; - - cout << a * 2 << endl; - cout << 2 * a << endl; -} - - - -/* - Задачи: - - 1) В этой программе выражение a * 2 вычисляется правильно, но - выражение 2 * a даёт ошибку. - - Из-за чего это происходит? Исправьте ситуацию так, чтобы выражение 2 * a также вычислялось. - - - 2) Можно ли сделать перегруженный оператор << методом класса Point? -*/ - - diff --git a/seminar02_encapsulation/classroom_tasks/code/1point/02operator_order_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/1point/02operator_order_solution.cpp deleted file mode 100644 index 8675d08..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/1point/02operator_order_solution.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - Решения: - - 1) Выражение a * 2 вычисляется так как есть перегруженный оператор a.operator*(2) - Выражение 2 * a даёт ошибку так как не было перегруженного оператора operator*(2, a) - - Но его можно просто написать, как это сделано ниже. - - Сделать этот оператор методом мы не можем, так как перегруженный оператор может быть методом - только первого аргумента, первый аргумент в данном случае это число целочисленного типа float. - Добавить метод в тип float мы не можем, так как float это вообще не класс. - - Замечание: Литерал 2 на самом деле имеет тип int, но int может конвертироваться во float если нужно - - - 2) Можно ли сделать перегруженный оператор << методом класса Point? - - Нет, нельзя. Перегруженный оператор может быть методом только первого аргумента. -*/ - -#include -#include -#include -using std::cout, std::endl; - - - -struct Point -{ - float x, y; - - Point operator*(float k) const - { - Point result = {k * x, k * y}; - return result; - } - -}; - -Point operator*(float k, Point a) -{ - return a * k; -} - - -std::ostream& operator<<(std::ostream& out, Point a) -{ - out << std::setprecision(2) << "(" << a.x << ", " << a.y << ")"; - return out; -} - - -int main() -{ - Point a = {2.1, 1.5}; - - cout << a * 2 << endl; - cout << 2 * a << endl; -} - - - - - diff --git a/seminar02_encapsulation/classroom_tasks/code/1point/03setters_getters.cpp b/seminar02_encapsulation/classroom_tasks/code/1point/03setters_getters.cpp deleted file mode 100644 index d9269a0..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/1point/03setters_getters.cpp +++ /dev/null @@ -1,124 +0,0 @@ -/* - До этого момента поля x и y класса Point были публичными - - Обычно, мы не хотим делать поля публичными, так как мы не хотим, чтобы поля могли бы быть заданы некоректным значением извне класса. - Однако, в случае класса Point некорректных значений для x и y просто не существует - любое вещественное число будет - корректным для значения координаты точки. - Поэтому нет ничего плохого, чтобы сделать x и y публичными для класса Point - - - Но давайте сделаем класс с немного более сложным поведением. - Точка RestrictedPoint - это будет точка, которая может находится только в квадрате [0,1]x[0,1] - То есть поле x может принимать значения только от 0 до 1 и поле y может принимать значения только от 0 до 1. - - Сделаем поля x и y приватными (и назовём их mx и my) - Теперь до них можно будет доступиться только в методах класса RestrictedPoint и в друзьях. - - Чтобы можно было работать с этими полями вне класса напишем методы - getx, gety, setx, sety - Такие методы для получения полей и записи в поля класса называются геттерами и сеттерами - Функции getx и gety просто возвращают соответствующие координаты - Функции setx и sety меняют соответствующие координаты и следят, чтобы они находились в диапазоне от 0 до 1 - - - Нам понадобится стандартная функция std::clamp из , которая принимает на вход три числа и - если первое число находится в промежутке между вторым и третьим, то clamp возвращает первое число - если первое число меньше, чем второе, то clamp возвращает второе число - если первое число больше, чем третье, то clamp возвращает третье число - Грубо говоря clamp ограничивает число в заданых пределах -*/ - -#include -#include -#include -using std::cout, std::endl; - - - -class RestrictedPoint -{ -private: - float mx, my; - -public: - - RestrictedPoint(float x, float y) - { - mx = std::clamp(x, 0.0f, 1.0f); - my = std::clamp(y, 0.0f, 1.0f); - } - - RestrictedPoint() - { - mx = 0; - my = 0; - } - - float getx() const - { - return mx; - } - - float gety() const - { - return my; - } - - void setx(float x) - { - mx = std::clamp(x, 0.0f, 1.0f); - } - - void sety(float y) - { - my = std::clamp(y, 0.0f, 1.0f); - } - - float norm() const - { - return std::sqrt(mx*mx + my*my); - } - - RestrictedPoint operator+(const RestrictedPoint& right) const - { - RestrictedPoint result; - result.mx = std::clamp(mx + right.mx, 0.0f, 1.0f); - result.my = std::clamp(my + right.my, 0.0f, 1.0f); - return result; - } -}; - - -std::ostream& operator<<(std::ostream& out, const RestrictedPoint& a) -{ - out << "(" << a.getx() << ", " << a.gety() << ")"; - return out; -} - - -int main() -{ - RestrictedPoint a = RestrictedPoint(0.5, 1.2); - cout << a << endl; - - a.setx(2); - cout << a << endl; - - a.sety(-5); - cout << a << endl; - - - RestrictedPoint b = RestrictedPoint(0.4, 0.2); - RestrictedPoint c = RestrictedPoint(0.8, 0.4); - cout << c + b << endl; -} - - - - -/* - Задача: - - 1) Добавьте к классу RestrictedPoint оператор умножения на число типа float - -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/00string.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/00string.cpp deleted file mode 100644 index 04955a2..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/00string.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - Создадим свою строку - - Один из самых главных недостатков языка C это работа со строками. - Строки в языке C это просто массивы элементов типа char - char str[100]; или char* p = malloc(100); - - В языке C работать со строками очень неудобно по многим причинам: - - Нужно постоянно следить за тем, чтобы строка умещалась в памяти, которая под нею выделена. - - Строку можно выделить на Стеке, используя обычный массив, и тогда её вместимость нельзя будет увеличить, - а можно выделить в Куче, но тогда придётся самостоятельно выделять и освобождать память - и следить, чтобы не произошли утечки памяти. - - Строки нельзя просто копировать, сравнивать, складывать и т. д. Для этого нужно использовать - специальные функции типа strcpy и другие функции из библиотеки . - - - Создадим же удобный класс строки - Такой чтобы можно было удобно создавать строки, приравнивать, складывать и сравнивать. - Не заботясь о выделении/удалении памяти, и о том, что строка помещается в выделенную память. - - Чтобы можно было писать вот такой код: - - String a = "Cat"; - String b = "Dog"; - cout << a << " " << b << endl; - - String c = "Mouse"; - c = a + b; - c += "Bear"; - - if (c == "CatDogBear") - cout << "Yes" << endl; - - c = a; - cout << c << endl; - - - (String в переводе с английского это Строка) -*/ - - - - -int main() {} - diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/01constructor.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/01constructor.cpp deleted file mode 100644 index 11603f4..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/01constructor.cpp +++ /dev/null @@ -1,165 +0,0 @@ -/* - - Создадим строку, которая при создании (т.е в конструкторе) будет автоматически выделять необходимую память в Куче. - В чём-то реализация этой строки будет похожа на реализацию динамического массива из прошлого семестра. - - У класса строки 3 поля: - - mSize - размер - количество символов в строке (без учёта \0) - mCapacity - вместимость - количество выделенной памяти в Куче - mpData - указатель на выделенную память в Куче. В этой памяти строка будет иметь такой же вид, как и строка языка C. - В частности она будет иметь символ '\0' на конце. - Символ '\0' на конце оставим, чтобы было удобно конвертировать нашу строку в строку в стиле C. - - - Размер и вместимость это разные величины. - - Например, для хранения строки "Cat" может быть выделено памяти под 10 символов, хоть и под эту строку было бы достаточно всего 4. - Представьте, что у вас есть длинная строка и вы хотите удалить последний символ в ней. - Если бы мы не хранили вместимость, а всегда выделяли памяти в притык, то в этом простом случае нам бы пришлось - перевыделять память и копировать всю строку в новую память. - Если же мы храним вместимость, то достаточно всего лишь уменьшить размер на 1 и поставит \0 в новый конец строки. - - - - Теперь создадим конструктор, который будет выделять память и заполнять его нужным образом - - Конструктор String(const char* str) конструирует нашу строку из строки в стиле C. - Принимаем на вход именно константную строку, так как в этом случае в конструктор можно будет - передать как константные, так и неконстантые строки. - Если бы мы написали так String(char* str) , то в конструктор нельзя было бы передать константные строки. - - - В строках: - - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - мы находим размер переданной строки (strlen не используем, чтобы не связываться со старой библиотекой) - Вместимость на 1 больше, так как нужно учесть память под символ /0 - - - В строке: - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - выделяем необходимую память - - - В строках: - - for (size_t i = 0; str[i] != '\0'; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - - копируем содержимое переданной строки в только что выделенную память. - - - Другие методы класса String: - - getSize - возвращает размер строки - getCapacity - возвращает вместимость строки - cStr - возвращает строку в стиле C, то есть указатель на массив из char-ов с конечным символом \0 -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i] != '\0'; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - - size_t getSize() const - { - return mSize; - } - - size_t getCapacity() const - { - return mCapacity; - } - - const char* cStr() const - { - return mpData; - } -}; - - -std::ostream& operator<<(std::ostream& out, const String& s) -{ - out << s.cStr(); - return out; -} - - -int main() -{ - String a = "Cat"; - String b = "Dog"; - String c = "Lion"; - - cout << a << endl << b << endl << c << endl; -} - - -/* - Задание: - - 1) Создайте конструктор String(), который будет создавать пустую строку - (mSize = 0, mCapacity = 1, строка mpData содержит в себе 1 символ ('\0')) - - Конструктор, который не принимает аргументов называется конструктором по умолчанию - - - 2) Создайте конструктор String(size_t n, char a), который будет создавать строку из n символов a - (mSize = n, mCapacity = n + 1, строка mpData содержит в себе n + 1 символ (n раз a и '\0')) - - - 2) Создайте конструктор String(const String& s), который будет создавать строку String из другой строки String - (mSize = s.mSize, mCapacity = s.mCapacity, строка mpData содержит в себе копию строки s.mpData) - - Конструктор, который создаёт объект по другому объекту такого же типа называется конструктором копирования. - - - Протестируйте эти конструкторы: - String a; - cout << a << endl; - - String b(10, 'q'); - cout << b << endl; - - String c("Cat"); - cout << c << endl; - - String d(c); - cout << d << endl; -*/ diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/01constructor_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/01constructor_solution.cpp deleted file mode 100644 index e3e6699..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/01constructor_solution.cpp +++ /dev/null @@ -1,104 +0,0 @@ -#include -#include -using std::cout, std::endl, std::size_t; - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - cout << "Construtor from const char*" << endl; - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i] != '\0'; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() - { - cout << "Default Construtor" << endl; - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - mpData[0] = '\0'; - } - - String(size_t n, char a) - { - cout << "Construtor n equal characters" << endl; - mSize = n; - mCapacity = n + 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = a; - mpData[mSize] = '\0'; - } - - - String(const String& s) - { - cout << "Copy Constructor" << endl; - mSize = s.mSize; - mCapacity = s.mCapacity; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = s.mpData[i]; - mpData[mSize] = '\0'; - } - - size_t getSize() const - { - return mSize; - } - - size_t getCapacity() const - { - return mCapacity; - } - - const char* cStr() const - { - return mpData; - } -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - String a; - cout << a << endl << endl; - - String b(10, 'q'); - cout << b << endl << endl; - - - String c = "Cat"; - cout << c << endl << endl; - - - String d(c); - cout << c << endl << endl; -} diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/02delegated_constructor.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/02delegated_constructor.cpp deleted file mode 100644 index fbee670..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/02delegated_constructor.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - Делегирующий конструктор - - В разных конструкторах может быть повторяющийся код. - Повторений кода иногда можно избежать если писать один конструктор на основе уже написанного. - - Это можно сделать с помощью синтаксиса так называемого делегирующего конструктора - После объявления конструктора, но перед его телом можно написать двоеточие и вызвать другой конструктор - - Например: - - String() : String("") - { - cout << "Default Constructor" << endl; - } - - Этот конструктор сначала вызовет конструктор String(const char* str) с аргументом "" (то есть пустой строкой) - а потом исполнит тело данного коструктора (в данном случае напечатает Default Constructor). -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - cout << "Constructor" << endl; - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i] != '\0'; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") - { - cout << "Default Constructor" << endl; - } - - - String(const String& s) : String(s.cStr()) - { - cout << "Copy Constructor" << endl; - } - - size_t getSize() const - { - return mSize; - } - - size_t getCapacity() const - { - return mCapacity; - } - - const char* cStr() const - { - return mpData; - } -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - String a; - cout << "a = " << a << endl << endl; - - - String b = "Cat"; - cout << "b = " << b << endl << endl; - - - String c(b); - cout << "c = " << c << endl << endl; -} - - - - - -/* - Задача: - - Попробуйте понять без запуска, что напечатает данная программа -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/03destructor.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/03destructor.cpp deleted file mode 100644 index 6557d30..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/03destructor.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - В конструкторе мы выделили память с malloc, но нигде в программе её не освободили - Соответственно, в предыдущей программе у нас есть очень серьёзная ошибка - утечка памяти. - - Где же нужно освобождать память? - Если память была выделена в конструкторе при создании объекта, то выделять её нужно при удалении объекта. - Для того, чтобы испольнить ваш код при удалении объекта существует специальный метод, который называется Деструктор. - - - Деструктор - это специальный метод, который вызывается тогда, когда объект уничтожается - Объекты, созданные на стеке удаляются при выходе из области видимости - - - Синтаксис деструктора такой: - - ~String() - { - ... - } -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - - String(const char* str) - { - cout << "Constructor of " << str << endl; - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i] != '\0'; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - - ~String() - { - cout << "Destructor of " << mpData << endl; - std::free(mpData); - } - - - size_t getSize() const - { - return mSize; - } - - size_t getCapacity() const - { - return mCapacity; - } - - const char* cStr() const - { - return mpData; - } -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - String a = "Cat"; - String b = "Dog"; - - if (true) - { - String c = "Lion"; - } - - String c = "Bear"; -} - - - -/* - Задание: - - 1) Что напечатает данная программа? - В каком порядке вызовутся конструкторы - - - 2) Если создать строку String в цикле, то будут ли каждую итерацию вызываться конструкторы и деструкторы? - - for (int i = 0; i < 10; ++i) - { - String s = "Elephant"; - } -*/ diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/04operator_addition.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/04operator_addition.cpp deleted file mode 100644 index 7dc87fb..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/04operator_addition.cpp +++ /dev/null @@ -1,94 +0,0 @@ -/* - Оператор сложения - - Оператор сложения для строк должен принимать 2 строки и возвращать новую строку, равную результату конкатенации двух строк - Если строка a = "Cat" , а строка b = "Mouse" , то их конкатенация это a + b = "CatMouse" - - Оператор сложения должен принимать свои аргументы по константной ссылке - по ссылке, чтобы не копировать объект лишний раз при передаче в функцию - по константной, потому что мы не будем менять принимаемые объекты внутри функции - - - То есть прототип оператора сложения, если его делать с помощью обычной функции, должен выглядеть так: - - String operator+(const String& a, const String& b) - - - Прототип оператора сложения, если его делать с помощью метода класса String, должен выглядеть так: - - String operator+(const String& b) const -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - cout << "Constructor of " << str << endl; - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i] != '\0'; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - - ~String() - { - cout << "Destructor of " << mpData << endl; - std::free(mpData); - } - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - String a = "Cat"; - String b = "Mouse"; - - cout << a + b << endl; -} - - - -/* - Задание: - - 1) Написать оператор сложения для строки String в виде свободной функции - В этом случае эту функцию нужно сделать дружественной классу String, - чтобы она имела доступ к приватным полям класса - - 2) Написать оператор сложения для строки String в виде метода класса String -*/ diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/04operator_addition_solution1.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/04operator_addition_solution1.cpp deleted file mode 100644 index b59f25e..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/04operator_addition_solution1.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include -using std::cout, std::endl, std::size_t; - - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i] != '\0'; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - - ~String() - { - std::free(mpData); - } - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} - - friend String operator+(const String& a, const String& b); -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - -String operator+(const String& a, const String& b) -{ - String result; - - result.mSize = a.mSize + b.mSize; - result.mCapacity = result.mSize + 1; - result.mpData = (char*)std::malloc(sizeof(char) * result.mCapacity); - - for (size_t i = 0; i < a.mSize; ++i) - result.mpData[i] = a.mpData[i]; - - for (size_t i = 0; i < b.mSize; ++i) - result.mpData[a.mSize + i] = b.mpData[i]; - - result.mpData[result.mSize] = '\0'; - - return result; -} - - -int main() -{ - String a = "Cat"; - String b = "Mouse"; - - cout << a + b << endl; -} - - - diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/04operator_addition_solution2.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/04operator_addition_solution2.cpp deleted file mode 100644 index c3b3eaf..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/04operator_addition_solution2.cpp +++ /dev/null @@ -1,86 +0,0 @@ -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - String operator+(const String& b) - { - String result; - - result.mSize = mSize + b.mSize; - result.mCapacity = result.mSize + 1; - result.mpData = (char*)std::malloc(sizeof(char) * result.mCapacity); - - for (size_t i = 0; i < mSize; ++i) - result.mpData[i] = mpData[i]; - - for (size_t i = 0; i < b.mSize; ++i) - result.mpData[mSize + i] = b.mpData[i]; - - result.mpData[result.mSize] = '\0'; - - return result; - } - - - ~String() - { - std::free(mpData); - } - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} - - friend String operator+(const String& a, const String& b); -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - - -int main() -{ - String a = "Cat"; - String b = "Mouse"; - - cout << a + b << endl; -} - - - diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/05operator_assignment.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/05operator_assignment.cpp deleted file mode 100644 index 4775647..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/05operator_assignment.cpp +++ /dev/null @@ -1,126 +0,0 @@ -/* - Оператор присваивания - - Оператор присваивания можно сделать только в виде метода - Такой метод должен - - принимать один аргумент - это правый аргумент оператора присваивания, - - менять объект, вызвавший оператор (то есть левый аргумент оператора присваивания) - - возвращать ссылку на объект, вызвавший оператор (то есть объект слева от оператора присваивания) - - - Почему оператор присваивания должен возвращать ссылку на левый аргумент? - Чтобы оператор присваивания работал аналогично тому как работает оператор присваивания для обычных типов - - Рассмотрим следующий пример: - - int a, b, c; - a = b = c = 123; // все переменные станут равны 123, операторы выполняются справа налево - - (a = 1) = 2; // a станет равной 2 - - - Мы хотим, чтобы и такой код работал: - - String a, b, c; - a = b = c = "Cat"; - - (a = "Dog") = "Mouse"; - - - Прототип оператора присваивания как метода класса String должен выглядеть так: - - String& operator=(const String& b) -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - - ~String() - { - std::free(mpData); - } - - - String& operator=(const String& right) - { - // Ваш код нужно написать здесь - } - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - String a = "Cat"; - String b = "Mouse"; - String c; - - a = b; - cout << a << endl; - - a = b = c = "Elephant"; - cout << a << endl; - cout << b << endl; - cout << c << endl; - - (a = "Dog") = "Axolotl"; - cout << a << endl; - - a = a; - cout << a << endl; -} - - - -/* - Задание: - - 1) Написать оператор присваивания для строки String в виде метода класса String - - Не забудьте учесть случай: - - String a = "Cat"; - a = a; -*/ diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/05operator_assignment_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/05operator_assignment_solution.cpp deleted file mode 100644 index 9f74f17..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/05operator_assignment_solution.cpp +++ /dev/null @@ -1,92 +0,0 @@ -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - - ~String() - { - std::free(mpData); - } - - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - String a = "Cat"; - String b = "Mouse"; - String c; - - a = b; - cout << a << endl; - - a = b = c = "Elephant"; - cout << a << endl; - cout << b << endl; - cout << c << endl; - - (a = "Dog") = "Axolotl"; - cout << a << endl; - -} diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/06operator_addition_assignment.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/06operator_addition_assignment.cpp deleted file mode 100644 index c00d277..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/06operator_addition_assignment.cpp +++ /dev/null @@ -1,132 +0,0 @@ -/* - Оператор присваивания сложения += - - Очень похож на оператор присваивания, разница только в том, каким станет левый операнд после применения этого оператора - К левому операнду в этом случае должна прибавиться копия правого оператора - - Если a = "Cat" , b = "Dog" , то после применения a += b строка a будет равна "CatDog" - - - - Прототип оператора присваивания сложения как метода класса String должен выглядеть так: - - String& operator+=(const String& b) -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - - ~String() - { - std::free(mpData); - } - - String operator+(const String& b) - { - String result; - - result.mSize = mSize + b.mSize; - result.mCapacity = result.mSize + 1; - result.mpData = (char*)std::malloc(sizeof(char) * result.mCapacity); - - for (size_t i = 0; i < mSize; ++i) - result.mpData[i] = mpData[i]; - - for (size_t i = 0; i < b.mSize; ++i) - result.mpData[mSize + i] = b.mpData[i]; - - result.mpData[result.mSize] = '\0'; - - return result; - } - - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - - - String& operator+=(const String& right) - { - // Ваш код нужно написать здесь - } - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - String a = "Mouse"; - String b = "Elephant"; - - b += a; - - cout << b << endl; -} - - - -/* - Задание: - - 1) Написать оператор присваивания сложения для строки String в виде метода класса String - - Подсказка: можно использовать уже написанные операторы, чтобы реализовать этот -*/ diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/06operator_addition_assignment_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/06operator_addition_assignment_solution.cpp deleted file mode 100644 index 8b06b3a..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/06operator_addition_assignment_solution.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - - ~String() - { - std::free(mpData); - } - - String operator+(const String& b) - { - String result; - - result.mSize = mSize + b.mSize; - result.mCapacity = result.mSize + 1; - result.mpData = (char*)std::malloc(sizeof(char) * result.mCapacity); - - for (size_t i = 0; i < mSize; ++i) - result.mpData[i] = mpData[i]; - - for (size_t i = 0; i < b.mSize; ++i) - result.mpData[mSize + i] = b.mpData[i]; - - result.mpData[result.mSize] = '\0'; - - return result; - } - - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - - - String& operator+=(const String& right) - { - *this = *this + right; - return *this; - } - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - String a = "Mouse"; - String b = "Elephant"; - - b += a; - - cout << b << endl; -} - diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/07operator_addition_alt.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/07operator_addition_alt.cpp deleted file mode 100644 index 31dc20c..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/07operator_addition_alt.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - По решению предыдущего занятия понятно, что операторы + = и += взаимосвязаны. - - Если реализованы операторы + и = можно, используя их, реализовать оператор += - Если реализованы операторы = и += можно, используя их, реализовать оператор + -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - - ~String() - { - std::free(mpData); - } - - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - String& operator+=(const String& right) - { - if (mCapacity < mSize + right.mSize + 1) - { - mCapacity = mSize + right.mSize + 1; - char* pNewData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - pNewData[i] = mpData[i]; - - std::free(mpData); - mpData = pNewData; - } - - for (size_t i = 0; i < right.mSize; ++i) - mpData[mSize + i] = right.mpData[i]; - - mSize += right.mSize; - mpData[mSize] = '\0'; - - return *this; - } - - String operator+(const String& b) - { - - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - String a = "Mouse"; - String b = "Elephant"; - - cout << a + b << endl; -} - - - -/* - Задача: - - 1) Напишите оператор + , используя операторы = и += - -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/07operator_addition_alt_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/07operator_addition_alt_solution.cpp deleted file mode 100644 index 9a51e3c..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/07operator_addition_alt_solution.cpp +++ /dev/null @@ -1,108 +0,0 @@ -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - - ~String() - { - std::free(mpData); - } - - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - String& operator+=(const String& right) - { - if (mCapacity < mSize + right.mSize + 1) - { - mCapacity = mSize + right.mSize + 1; - char* pNewData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - pNewData[i] = mpData[i]; - - std::free(mpData); - mpData = pNewData; - } - - for (size_t i = 0; i < right.mSize; ++i) - mpData[mSize + i] = right.mpData[i]; - - mSize += right.mSize; - mpData[mSize] = '\0'; - - return *this; - } - - String operator+(const String& b) - { - String result = *this; - result += b; - return result; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - String a = "Mouse"; - String b = "Elephant"; - - cout << a + b << endl; -} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/08comparasion_operators.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/08comparasion_operators.cpp deleted file mode 100644 index 74563db..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/08comparasion_operators.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* - Операторы сравнения == != > >= < <= - - К строкам можно применять операторы сравнения. - - Очевидно, когда строки равны: должны быть равны размеры строк (mSize) и все символы от 0 до mSize - При этом вместимость (mCapacity) у равных строк может отличаться - - Как сравнивать строки на больше/меньше? В этом случае сравниваем лексикографически, то есть, по алфавиту. - То слово, которое находилось бы в орфографическом словаре позже и будет большим. - Например, "Cat" > "Camel" так как первые 2 буквы совпадают, а третья буква у слова Cat идёт дальше по алфавиту - - - Более точное сравнение такое: мы сравниваем посимвольно до первого несовпадающего символа - Если мы нашли первые несовпадающий символ и не дошли до конца в обоих строках, то та строка будет больше, - у которой этот символ больше. - -*/ - -#include -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - ~String() - { - std::free(mpData); - } - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - cout << std::boolalpha; - - String a = "Cat"; - String b = "Camel"; - - cout << (a > b) << endl; - cout << (a < b) << endl; - cout << (a == b) << endl; - cout << (a == a) << endl; - - - String c = "Catharsis"; - - cout << (a > c) << endl; - cout << (a < c) << endl; - cout << (a == c) << endl; - cout << (a != c) << endl; -} - - - -/* - Задача: - - 1) Напишите операторы == != > >= < <= для класса String - Подсказка: можно использовать уже написанные сравнения - Например, если вы написали оператор > , то очень просто написать оператор <= , используя оператор > - -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/08comparasion_operators_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/08comparasion_operators_solution.cpp deleted file mode 100644 index 43e2026..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/08comparasion_operators_solution.cpp +++ /dev/null @@ -1,140 +0,0 @@ -#include -#include -#include -using std::cout, std::endl, std::size_t; - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - - ~String() - { - std::free(mpData); - } - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - - bool operator==(const String& right) const - { - if (mSize != right.mSize) - return false; - - size_t i = 0; - while (i < mSize && mpData[i] == right.mpData[i]) - i++; - - return i == mSize; - } - - bool operator<(const String& right) const - { - size_t i = 0; - while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) - i++; - - return mpData[i] < right.mpData[i]; - } - - bool operator<=(const String& right) const - { - size_t i = 0; - while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) - i++; - - return mpData[i] <= right.mpData[i]; - } - - bool operator!=(const String& right) const - { - return !(*this == right); - } - - bool operator>(const String& right) const - { - return !(*this <= right); - } - - bool operator>=(const String& right) const - { - return !(*this < right); - } - - - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - cout << std::boolalpha; - - String a = "Cat"; - String b = "Camel"; - - cout << (a > b) << endl; - cout << (a < b) << endl; - cout << (a == b) << endl; - cout << (a == a) << endl; - - - String c = "Catharsis"; - - cout << (a > c) << endl; - cout << (a < c) << endl; - cout << (a == c) << endl; - cout << (a != c) << endl; -} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/09subscript_operator.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/09subscript_operator.cpp deleted file mode 100644 index 2dfb9b5..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/09subscript_operator.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* - Операторы индексации [] - - Чтобы получить доступ к одному символу у строки в стиле C можно использовать оператор индексации (квадратные скобочки). - Хотелось бы иметь такую же возможность и для нашей строки. - - Для этого можно перегрузить оператор индексации: - - char& operator[](size_t i) - - Этот оператор вызавется при взятии символа по индексу, например, если a это строка типа String, - - a[i] будет восприниматься компилятором как a.operator[](i) - - - Оператор индексации должен возвращать ссылку на символ, чтобы можно было менять соответствующий символ - - a[i] = 'A'; -*/ - -#include -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - - ~String() - { - std::free(mpData); - } - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - String a = "Cat"; - - cout << a[0] << endl; - cout << a[2] << endl; - cout << a[4] << endl; - - - cout << a.at(0) << endl; - cout << a.at(2) << endl; - cout << a.at(4) << endl; - -} - - - -/* - Задача: - - 1) Напишите оператор индексации для класса String - - - 2) Напишите метод at, который будет работать аналогично оператору индексации, только с тем отличием, что - если на вход приходит неправильный индекс (т. е. индекс >= mSize), то метод at должен печатать сообщение - об ошибке и завершать программу. - Для завершения программы используйте функцию std::exit(1) из библиотеки . - -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/09subscript_operator_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/09subscript_operator_solution.cpp deleted file mode 100644 index f7ed062..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/09subscript_operator_solution.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - - ~String() - { - std::free(mpData); - } - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - char& at(size_t i) - { - if (i >= mSize) - { - cout << "Error! Index is out of bounds." << endl; - std::exit(1); - } - return mpData[i]; - } - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - String a = "Cat"; - - cout << a[0] << endl; - cout << a[2] << endl; - cout << a[4] << endl; - - - cout << a.at(0) << endl; - cout << a.at(2) << endl; - cout << a.at(4) << endl; - -} diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/10reserve_and_resize.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/10reserve_and_resize.cpp deleted file mode 100644 index 694065f..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/10reserve_and_resize.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* - Напишем ещё 2 очень полезных метода: - - 1) reserve - увеличивает вместимость строки, на вход методу передаётся новая вместмость - если новая вместимость меньше старой, то ничего не происходит (вместимость не уменьшается) - размер и содержимое строки не меняется - - - 2) resize - изменяет размер строки, на вход методу передаётся новый размер - если новый размер меньше старого, то строка усекается - при необходимости увеличивает вместимость - - Используя эти два метода можно немного упростить код для операторов сложения и присваивания. - Эти методы могут быть полезны и для программиста, который будет работать с нашей строкой, поэтому сделаем их публичными. -*/ - -#include -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - - ~String() - { - std::free(mpData); - } - - - void reserve(size_t capacity) - { - if (capacity <= mCapacity) - return; - - mCapacity = capacity; - char* newData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - newData[i] = mpData[i]; - newData[mSize] = '\0'; - - std::free(mpData); - mpData = newData; - } - - - void resize(size_t size) - { - reserve(size + 1); - mSize = size; - mpData[mSize] = '\0'; - } - - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - mSize = right.mSize; - resize(mSize); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - - String operator+(const String& b) - { - String result; - result.resize(mSize + b.mSize); - - for (size_t i = 0; i < mSize; ++i) - result.mpData[i] = mpData[i]; - - for (size_t i = 0; i < b.mSize; ++i) - result.mpData[mSize + i] = b.mpData[i]; - - result.mpData[result.mSize] = '\0'; - - return result; - } - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - String a = "Cat"; - String b = "Dog"; - - cout << a.getCapacity() << endl; - a.reserve(10); - cout << a.getCapacity() << endl; - - cout << a + b << endl; - - - String c = "Sapere Aude"; - cout << c << endl; - - c.resize(6); - cout << c << endl; -} diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/10reserve_and_resize_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/10reserve_and_resize_solution.cpp deleted file mode 100644 index 5f704fd..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/10reserve_and_resize_solution.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include -#include -#include -using std::cout, std::cin, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - - ~String() - { - std::free(mpData); - } - - - void reserve(size_t capacity) - { - if (capacity <= mCapacity) - return; - - mCapacity = capacity; - char* newData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - newData[i] = mpData[i]; - newData[mSize] = '\0'; - - std::free(mpData); - mpData = newData; - } - - - void resize(size_t size) - { - reserve(size + 1); - mSize = size; - mpData[mSize] = '\0'; - } - - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - mSize = right.mSize; - resize(mSize); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - - String operator+(const String& b) - { - String result; - result.resize(mSize + b.mSize); - - for (size_t i = 0; i < mSize; ++i) - result.mpData[i] = mpData[i]; - - for (size_t i = 0; i < b.mSize; ++i) - result.mpData[mSize + i] = b.mpData[i]; - - result.mpData[result.mSize] = '\0'; - - return result; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - String a = "Cat"; - String b = "Dog"; - - cout << a.getCapacity() << endl; - a.reserve(10); - cout << a.getCapacity() << endl; - - cout << a + b << endl; - - - String c = "Sapere Aude"; - cout << c << endl; - - c.resize(6); - cout << c << endl; -} diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/11cin_string_overload.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/11cin_string_overload.cpp deleted file mode 100644 index d91d9ee..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/11cin_string_overload.cpp +++ /dev/null @@ -1,166 +0,0 @@ -/* - Считывание строки с экрана - - Помимо удобной печати на экран с помощью объекта std::cout, хотелось бы добавить удобное считываие строки - с помощью объекта std::cin. - - Для этого нужно перегрузить оператор >> с объектами типа std::istream и String, то есть написать функцию: - - std::istream& operator>>(std::istream& in, String& str) - - Эта функция должна считывать символы из стандартного входа и добавлять в строку - Основная проблема в том, что мы не знаем сколько символов нужно считать, поэтому нужно считывать - посимвольно и добавлять символы по одному в строку пока не встретим пробельный символ (' ' или '\n' или '\t') - - Для упрощения программы можно написать дополнительные методы - - void clear() - метод, который будет очищать строку - mSize = 0, mCapacity = 1, строка по адресу mpData равна "\0" - - void addCharacter(char c) - добавляет символ в конец строки - если у строки не хватает вместимости, то удваивает вместимость. - - - Для того, чтобы считать символ из стандартного входа можно использовать метод get класса istream - Этот метод возвращает следующий символ из стандартного входа - - char x = cin.get(); -*/ - -#include -#include -#include -using std::cout, std::cin, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - - ~String() - { - std::free(mpData); - } - - - void reserve(size_t capacity) - { - if (capacity <= mCapacity) - return; - - mCapacity = capacity; - char* newData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - newData[i] = mpData[i]; - newData[mSize] = '\0'; - - std::free(mpData); - mpData = newData; - } - - - void resize(size_t size) - { - reserve(size + 1); - mSize = size; - mpData[mSize] = '\0'; - } - - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - mSize = right.mSize; - resize(mSize); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - - String operator+(const String& b) - { - String result; - result.resize(mSize + b.mSize); - - for (size_t i = 0; i < mSize; ++i) - result.mpData[i] = mpData[i]; - - for (size_t i = 0; i < b.mSize; ++i) - result.mpData[mSize + i] = b.mpData[i]; - - result.mpData[result.mSize] = '\0'; - - return result; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - -int main() -{ - String a, b; - cin >> a >> b; - cout << a + b; - - a.addCharacter('!'); - cout << a << endl; -} - - -/* - Задача: - - 1) Напишите метод clear. - - 2) Напишите метод addCharacter. - - 3) Напишите перегруженный оператор << для считывания строки с экрана. - -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/11cin_string_overload_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/11cin_string_overload_solution.cpp deleted file mode 100644 index 0afe413..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/11cin_string_overload_solution.cpp +++ /dev/null @@ -1,158 +0,0 @@ -#include -#include -#include -using std::cout, std::cin, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - - ~String() - { - std::free(mpData); - } - - - void reserve(size_t capacity) - { - if (capacity <= mCapacity) - return; - - mCapacity = capacity; - char* newData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - newData[i] = mpData[i]; - newData[mSize] = '\0'; - - std::free(mpData); - mpData = newData; - } - - - void resize(size_t size) - { - reserve(size + 1); - mSize = size; - mpData[mSize] = '\0'; - } - - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - mSize = right.mSize; - resize(mSize); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - - String operator+(const String& b) - { - String result; - result.resize(mSize + b.mSize); - - for (size_t i = 0; i < mSize; ++i) - result.mpData[i] = mpData[i]; - - for (size_t i = 0; i < b.mSize; ++i) - result.mpData[mSize + i] = b.mpData[i]; - - result.mpData[result.mSize] = '\0'; - - return result; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - void clear() - { - std::free(mpData); - - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - mpData[0] = '\0'; - } - - void addCharacter(char c) - { - if (mSize + 1 == mCapacity) - reserve(2 * mCapacity); - - mpData[mSize] = c; - resize(mSize + 1); - } - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& out, const String& s) -{ - out << s.cStr(); - return out; -} - - -std::istream& operator>>(std::istream& in, String& s) -{ - s.clear(); - while (true) - { - char x = in.get(); - if (x == ' ' || x == '\n' || x == '\t') - break; - s.addCharacter(x); - } - return in; -} - - -int main() -{ - String a, b; - cin >> a >> b; - cout << a + b << endl; - - a.addCharacter('!'); - cout << a << endl; -} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/12full_string.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/12full_string.cpp deleted file mode 100644 index 1868129..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/12full_string.cpp +++ /dev/null @@ -1,262 +0,0 @@ -/* - Собираем все методы вместе. Получилась строка, которой можно удобно пользоваться и не задумываться о выделении памяти. -*/ - -#include -#include -using std::cout, std::cin, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - String(size_t n, char a) - { - mSize = n; - mCapacity = n + 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = a; - mpData[mSize] = '\0'; - } - - ~String() - { - std::free(mpData); - } - - void reserve(size_t capacity) - { - if (capacity <= mCapacity) - return; - - mCapacity = capacity; - char* newData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - newData[i] = mpData[i]; - newData[mSize] = '\0'; - - std::free(mpData); - mpData = newData; - } - - - void resize(size_t size) - { - reserve(size + 1); - mSize = size; - mpData[mSize] = '\0'; - } - - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - mSize = right.mSize; - resize(mSize); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - - String operator+(const String& b) - { - String result; - result.resize(mSize + b.mSize); - - for (size_t i = 0; i < mSize; ++i) - result.mpData[i] = mpData[i]; - - for (size_t i = 0; i < b.mSize; ++i) - result.mpData[mSize + i] = b.mpData[i]; - - result.mpData[result.mSize] = '\0'; - - return result; - } - - String& operator+=(const String& right) - { - *this = *this + right; - return *this; - } - - bool operator==(const String& right) const - { - if (mSize != right.mSize) - return false; - - size_t i = 0; - while (i < mSize && mpData[i] == right.mpData[i]) - i++; - - return i == mSize; - } - - bool operator<(const String& right) const - { - size_t i = 0; - while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) - i++; - - return mpData[i] < right.mpData[i]; - } - - bool operator<=(const String& right) const - { - size_t i = 0; - while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) - i++; - - return mpData[i] <= right.mpData[i]; - } - - bool operator!=(const String& right) const - { - return !(*this == right); - } - - bool operator>(const String& right) const - { - return !(*this <= right); - } - - bool operator>=(const String& right) const - { - return !(*this < right); - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - char& at(size_t i) - { - if (i >= mSize) - { - cout << "Error! Index is out of bounds." << endl; - std::exit(1); - } - return mpData[i]; - } - - void clear() - { - std::free(mpData); - - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - mpData[0] = '\0'; - } - - void addCharacter(char c) - { - if (mSize + 1 == mCapacity) - reserve(2 * mCapacity); - - mpData[mSize] = c; - resize(mSize + 1); - } - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& out, const String& s) -{ - out << s.cStr(); - return out; -} - -std::istream& operator>>(std::istream& in, String& s) -{ - s.clear(); - while (true) - { - char x = in.get(); - if (x == ' ' || x == '\n' || x == '\t') - break; - s.addCharacter(x); - } - return in; -} - - -int main() -{ - String a = "Mouse"; - String b; - cin >> b; - String c = b; - - if (a + c == "MouseLion") - cout << "Yes" << endl; - else - cout << "No" << endl; - - - if (a > "Mice") - cout << "Yes" << endl; - else - cout << "No" << endl; - - - c[0] = 'P'; - cout << c << endl; - - c += a; - cout << c << endl; - - c = c + String(10, 'q'); - cout << c << endl; -} - - - -/* - Задача: - - - 1) Напищите программу, которая будет считывать слова (используйте cin) в бесконечном цикле и каждый - раз печатать сумму всех слов. Например, если пользователь ввёл Hello, то программа должна напечатать - Hello и запросить следующее слово. Если затем пользователь введёт World, то программа должна будет - напечатать HelloWorld и запросить следуещее слово и так далее. - Программа должна останавливаться если пользователь ввёл слово "quit". -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/13problem_init_vs_assignment.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/13problem_init_vs_assignment.cpp deleted file mode 100644 index 1157041..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/13problem_init_vs_assignment.cpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - Рассмотрим при каких условиях происходит вызов того или иного метода. - - Для этого будем использовать класс String, в котором была добавлена печать на экран для конструкторов, - деструктора и оператора присваивания. - Например, конструктор по умолчанию будет печатать Default Constructor и т. д. -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - cout << "String Constructor from const char* (" << str << ")" << endl; - - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; ++i) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() - { - cout << "String Default Constructor" << endl; - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char)); - mpData[0] = '\0'; - } - - String(const String& s) - { - cout << "String Copy Constructor (" << s.mpData << ")" << endl; - - size_t i = 0; - mSize = s.mSize; - mCapacity = mSize + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = s.mpData[i]; - mpData[mSize] = '\0'; - } - - ~String() - { - cout << "String Destructor (" << mpData << ")" << endl; - std::free(mpData); - } - - String& operator=(const String& right) - { - cout << "String Assignment Operator (" << right.mpData << ")" << endl; - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - - -int main() -{ - String a = "Cat"; - String b = a; -} - -/* - Задачи: - - 1) Какие методы вызовутся в строке - - String a = "Cat"; - - Выберите один из вариантов: - - а) Только конструктор из const char* - б) Только оператор присваивания - в) И конструктор из const char* и оператор присваивания - - - 2) Какие методы вызовутся в строке - - String b = a; - - Выберите один из вариантов: - - а) Только конструктор копирования - б) Только оператор присваивания - в) И конструктор копирования и оператор присваивания - - - - 3) Проверьте ваши догадки скомпилировав и запустив программу - -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/14problem_init_vs_assignment.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/14problem_init_vs_assignment.cpp deleted file mode 100644 index 4a6108b..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/14problem_init_vs_assignment.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - Рассмотрим при каких условиях происходит вызов того или иного метода. - - Для этого будем использовать класс String, в котором была добавлена печать на экран для конструкторов, - деструктора и оператора присваивания. - Например, конструктор по умолчанию будет печатать Default Constructor и т. д. -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - cout << "String Constructor from const char* (" << str << ")" << endl; - - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; ++i) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() - { - cout << "String Default Constructor" << endl; - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char)); - mpData[0] = '\0'; - } - - String(const String& s) - { - cout << "String Copy Constructor (" << s.mpData << ")" << endl; - - size_t i = 0; - mSize = s.mSize; - mCapacity = mSize + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = s.mpData[i]; - mpData[mSize] = '\0'; - } - - ~String() - { - cout << "String Destructor (" << mpData << ")" << endl; - std::free(mpData); - } - - String& operator=(const String& right) - { - cout << "String Assignment Operator (" << right.mpData << ")" << endl; - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - - -int main() -{ - String a = "Cat"; - String c; - c = a; -} - -/* - Задачи: - - 1) Какие методы класса String вызовутся в данной программе. - - 2) Проверьте ваши догадки, скомпилировав и запустив программу -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/14problem_init_vs_assignment_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/14problem_init_vs_assignment_solution.cpp deleted file mode 100644 index 0fdd67a..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/14problem_init_vs_assignment_solution.cpp +++ /dev/null @@ -1,36 +0,0 @@ -/* - Решения: - - 1) String a = "Cat"; - - Будет вызван только конструктор из const char* - - - - 2) String b = a; - - Будет вызван только конструктор копирования - - Несмотря на то, что в этих выражениях присутствует символ = оператор присваивания в этих случаях не вызывается. - - - - - 3) String c; - c = a; - - Будет вызван конструктор по умолчанию в строке String c; - А потом будет вызван оператор присваивания в строке c = a; - - - Получается символ = может использоваться для обозначения двух разных вещей: инициализации и присваивания. - - - String a = "Cat"; // Инициализация строкой "Cat" (вызов коструктора от const char*) - - String b = a; // Инициализация объектом a (вызов коструктора копирования) - - String c; // Инициализация по умолчанию (вызов конструктора по умолчанию) - c = a; // Присваивание (вызов метода operator=) - -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/15problem_pass_to_funciton.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/15problem_pass_to_funciton.cpp deleted file mode 100644 index f6651cf..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/15problem_pass_to_funciton.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* - Посмотрим какие особые методы вызываются при передаче объекта в функцию. -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - cout << "String Constructor from const char* (" << str << ")" << endl; - - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; ++i) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() - { - cout << "String Default Constructor" << endl; - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char)); - mpData[0] = '\0'; - } - - String(const String& s) - { - cout << "String Copy Constructor (" << s.mpData << ")" << endl; - - size_t i = 0; - mSize = s.mSize; - mCapacity = mSize + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = s.mpData[i]; - mpData[mSize] = '\0'; - } - - ~String() - { - cout << "String Destructor (" << mpData << ")" << endl; - std::free(mpData); - } - - String& operator=(const String& right) - { - cout << "String Assignment Operator (" << right.mpData << ")" << endl; - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - - -void print(String s) -{ - cout << s << endl; -} - - -int main() -{ - String a = "Cat"; - print(a); -} - -/* - Задачи: - - 1) Какие методы класса String вызовутся в данной программе. - - - 2) Проверьте ваши догадки скомпилировав и запустив программу - - - 3) Что если мы будем передавать объект String в функцию print не по значению, а по ссылке, то есть изменим - функцию print на следующую: - - void print(const String& s) - { - cout << s << endl; - } - - Какие методы будут вызваны теперь? - -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/15problem_pass_to_funciton_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/15problem_pass_to_funciton_solution.cpp deleted file mode 100644 index 3226cfd..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/15problem_pass_to_funciton_solution.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - Решения: - - 1) В случае: - - void print(String s) - { - cout << s << endl; - } - - int main() - { - String a = "Cat"; - print(a); - } - - Вызовутся следующие методы: - - 1) Конструктор строки из "Cat" - - - 2) При передаче объекта в функцию по значению, он должен быть скопирован. - Соответственно при вызове print(a) объект a должен скопироваться в объект s функции print. - Для обычных типов вроде int тут бы произошло побайтовое копирование, но для классов вызывается конструктор копирования. - - - 3) Внутри функции print объект s печатается на экран. Затем мы выходим из функции print и уничтожаем все локальные объекты этой функции. - Соответственно вызовется деструктор для объекта s. - - - 4) Затем мы выходим из функции main и уничтожаем все объекты, локальные для функции main. - Соответственно вызовется деструктор для объекта a. - - - - - 3) В случае: - - void print(const String& s) - { - cout << s << endl; - } - - int main() - { - String a = "Cat"; - print(a); - } - - Вызовутся следующие методы: - - 1) Конструктор строки из "Cat" - - - При передаче объекта в функцию по ссылке, этот объект в функцию не копируется. - Поэтому никаких конструкторов копирования не вызывается. - - - 2) Деструктор для строки a из функии main. - - - Получается, что обычно передавать объекты в функции более эффективно по ссылке, а не по значению. - -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/16problem_pass_to_funciton.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/16problem_pass_to_funciton.cpp deleted file mode 100644 index 317e2b2..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/16problem_pass_to_funciton.cpp +++ /dev/null @@ -1,131 +0,0 @@ -/* - Особые методы при передачах в функцию - - Посмотрим какие особые методы вызываются при передаче объекта в функцию -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - cout << "String Constructor from const char* (" << str << ")" << endl; - - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; ++i) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() - { - cout << "String Default Constructor" << endl; - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char)); - mpData[0] = '\0'; - } - - String(const String& s) - { - cout << "String Copy Constructor (" << s.mpData << ")" << endl; - - size_t i = 0; - mSize = s.mSize; - mCapacity = mSize + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = s.mpData[i]; - mpData[mSize] = '\0'; - } - - ~String() - { - cout << "String Destructor (" << mpData << ")" << endl; - std::free(mpData); - } - - String& operator=(const String& right) - { - cout << "String Assignment Operator (" << right.mpData << ")" << endl; - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - - -void changeFirstLetter(String s) -{ - s[0] = 'B'; -} - - -int main() -{ - String a = "Cat"; - cout << a << endl; - - changeFirstLetter(a); - cout << a << endl; -} - -/* - Задачи: - - 1) Какие методы класса String вызовутся в данной программе. - - 2) Проверьте ваши догадки скомпилировав и запустив программу - - 3) Функция changeFirstLetter должна была менять первую букву нашей строки на букву 'B', но это не происходит и - строка a после вызова changeFirstLetter(a) остаётся неизменной. - Почему это происходит и как изменить функцию changeFirstLetter чтобы она меняла первую букву переданной строки. -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/16problem_pass_to_funciton_solution.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/16problem_pass_to_funciton_solution.cpp deleted file mode 100644 index c689bb1..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/16problem_pass_to_funciton_solution.cpp +++ /dev/null @@ -1,136 +0,0 @@ -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - cout << "String Constructor from const char* (" << str << ")" << endl; - - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; ++i) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() - { - cout << "String Default Constructor" << endl; - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char)); - mpData[0] = '\0'; - } - - String(const String& s) - { - cout << "String Copy Constructor (" << s.mpData << ")" << endl; - - size_t i = 0; - mSize = s.mSize; - mCapacity = mSize + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = s.mpData[i]; - mpData[mSize] = '\0'; - } - - ~String() - { - cout << "String Destructor (" << mpData << ")" << endl; - std::free(mpData); - } - - String& operator=(const String& right) - { - cout << "String Assignment Operator (" << right.mpData << ")" << endl; - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - - -void changeFirstLetter(String& s) -{ - s[0] = 'B'; -} - - -int main() -{ - String a = "Cat"; - cout << a << endl; - - changeFirstLetter(a); - cout << a << endl; -} - -/* - Решение: - - В такую функцию: - - void changeFirstLetter(String s) - { - s[0] = 'B'; - } - - строка передавалась по значению и, следовательно, происходило копирование этой строки в объект s функции changeFirstLetter. - Функция changeFirstLetter меняла первую букву копии нашей строки, но оригинальная строка не менялась. - - - Для того, чтобы функция changeFirstLetter меняла оригинальную строку ей нужно передавать объект не по значению, а по ссылке вот так: - - void changeFirstLetter(String& s) - { - s[0] = 'B'; - } - -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/17problem_constructor_calls.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/17problem_constructor_calls.cpp deleted file mode 100644 index 63fd799..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/17problem_constructor_calls.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - Различный синтаксис вызова конструкторов -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - cout << "String Constructor from const char* (" << str << ")" << endl; - - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; ++i) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() - { - cout << "String Default Constructor" << endl; - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char)); - mpData[0] = '\0'; - } - - String(const String& s) - { - cout << "String Copy Constructor (" << s.mpData << ")" << endl; - - size_t i = 0; - mSize = s.mSize; - mCapacity = mSize + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = s.mpData[i]; - mpData[mSize] = '\0'; - } - - ~String() - { - cout << "String Destructor (" << mpData << ")" << endl; - std::free(mpData); - } - - String& operator=(const String& right) - { - cout << "String Assignment Operator (" << right.mpData << ")" << endl; - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - - -int main() -{ - String a = "Cat"; - - String b = String("Dog"); - - String c("Mouse"); - - String d = {"Tiger"}; - - String e = String{"Axolotl"}; - - String f {"Lion"}; -} - -/* - Ввиду того, что язык C++ имеет длинную историю, на протяжении которой в язык добавлялись новые возможности, - в языке существует множество способов сделать одно и то же разными способами. - - Один из ярких примеров этого является инициализация объекта. В этом примере создаются 6 строк. Синтаксис различается, - но в данном случае все эти строки по сути делают одно и то же: cоздают объект с помощью конструктора от const char*. - При этом не вызывается никаких конструкторов копирования или операторов присваивания. - - В современном языке C++ предпочтительным способом инициализации является вариант f: - - String f {"Lion"}; - - - - Задачи: - - 1) Что напечатает данная программа? - В каком порядке вызовутся конструкторы и в каком порядке вызовутся деструкторы? - - 2) Скомпилируйте программу и запустите, чтобы проверить ваши догадки. - - 3) Создайте 5 объектов типа String с помощью конструктора по умолчанию, используя разный синтаксис вызова конструктора. - - 4) Пусть есть объект x типа String: - - String x = "Cat"; - - Создайте 6 объектов типа String с помощью конструктора копирования, используя разный синтаксис вызова конструктора. - Все новые объекты должны копировать объект x. - -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/17problem_constructor_calls_solution1.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/17problem_constructor_calls_solution1.cpp deleted file mode 100644 index 1880951..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/17problem_constructor_calls_solution1.cpp +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - cout << "String Constructor from const char* (" << str << ")" << endl; - - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; ++i) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() - { - cout << "String Default Constructor" << endl; - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char)); - mpData[0] = '\0'; - } - - String(const String& s) - { - cout << "String Copy Constructor (" << s.mpData << ")" << endl; - - size_t i = 0; - mSize = s.mSize; - mCapacity = mSize + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = s.mpData[i]; - mpData[mSize] = '\0'; - } - - ~String() - { - cout << "String Destructor (" << mpData << ")" << endl; - std::free(mpData); - } - - String& operator=(const String& right) - { - cout << "String Assignment Operator (" << right.mpData << ")" << endl; - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - - -int main() -{ - String a; - - String b = String(); - - // String c(); - - String d = {}; - - String e = String{}; - - String f {}; -} - -/* - Аналогично есть множество вариантов синтаксиса вызова конструктора по умолчанию. - - Только такой вариант вызова конструктора не работает: - - String c(); - - Потому что в этом случае компилятор считает, что это объявление функции по имени c, которая ничего не принимает и возвращает объект типа String. - -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/17problem_constructor_calls_solution2.cpp b/seminar02_encapsulation/classroom_tasks/code/2string/17problem_constructor_calls_solution2.cpp deleted file mode 100644 index 812c132..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/2string/17problem_constructor_calls_solution2.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - cout << "String Constructor from const char* (" << str << ")" << endl; - - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; ++i) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() - { - cout << "String Default Constructor" << endl; - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char)); - mpData[0] = '\0'; - } - - String(const String& s) - { - cout << "String Copy Constructor (" << s.mpData << ")" << endl; - - size_t i = 0; - mSize = s.mSize; - mCapacity = mSize + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = s.mpData[i]; - mpData[mSize] = '\0'; - } - - ~String() - { - cout << "String Destructor (" << mpData << ")" << endl; - std::free(mpData); - } - - String& operator=(const String& right) - { - cout << "String Assignment Operator (" << right.mpData << ")" << endl; - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - - -int main() -{ - String x = "Cat"; - - - String a = x; - - String b = String(x); - - String c(x); - - String d = {x}; - - String e = String{x}; - - String f {x}; -} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/3default_methods/00special_methods.cpp b/seminar02_encapsulation/classroom_tasks/code/3default_methods/00special_methods.cpp deleted file mode 100644 index 4e2e462..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/3default_methods/00special_methods.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - Особые методы - - В прошлой части мы рассмотрели различные методы классов. Некоторые из этих методов называются особыми. - Они выделяются по сравнению с другими методами тем, что они будут создаваться автоматически даже если вы их не напишите. - К особым методам класса относятся: - - - 1) Конструктор по умолчанию. То есть конструктор, который не принимает ни одного аргумента. - В случае со строкой String это контруктор: - - String() - - - 2) Конструктор копирования. То есть конструктор, который создаёт объект из другого объекта такого же типа, что и данный. - В случае со строкой String это контруктор: - - String(const String& s) - - - 3) Деструктор. Это метод, который вызывается при удалении объекта. В отличии от конструкторов, деструктор у объекта всегда один. - В случае со строкой String это: - - ~String() - - - 4) Оператор присваивания. Это метод, который вызывается при присваивании одного метода класса String другому методу класса String. - В случае со строкой String это: - - String& operator=(const String& right) - - - - 5,6) Есть ещё 2 особых метода, которые мы пройдём позже. - - - Все остальные методы, включаю другие конструкторы и перегруженные операторы, к особым методам не относятся. - То есть остальные методы не могут создаваться автоматически. - - - В этой части мы рассмотрим при каких условиях происходит вызов того или иного особого метода. - Для этого будем использовать класс String, в котором была добавлена печать на экран для каждого особого метода и для коструктора из const char*. - Например, конструктор по умолчанию будет печатать Default Constructor и т. д. -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - cout << "String Constructor from const char* (" << str << ")" << endl; - - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; ++i) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() - { - cout << "String Default Constructor" << endl; - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char)); - mpData[0] = '\0'; - } - - String(const String& s) - { - cout << "String Copy Constructor (" << s.mpData << ")" << endl; - - size_t i = 0; - mSize = s.mSize; - mCapacity = mSize + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = s.mpData[i]; - mpData[mSize] = '\0'; - } - - ~String() - { - cout << "String Destructor (" << mpData << ")" << endl; - std::free(mpData); - } - - String& operator=(const String& right) - { - cout << "String Assignment Operator (" << right.mpData << ")" << endl; - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - - -class Book -{ -public: - String title; - int pages; - float price; -}; - - -int main() -{ - Book a = Book(); - cout << a.title << " " << a.pages << " " << a.price << endl; -} - - - -/* - У класса Book есть 3 поля, одно из которых имеет тип String. - Но у класса Book не определён ни один метод. У него нет никаких конструкторов или перегруженных операторов. - - Теперь посмотрим на код: - - Book a = Book(); - - Тут мы создаём объект типа Book с помощью конструктора по умолчанию. Но у Book не написан конструктор по умолчанию! - Что же произойдёт в этом случае? Ошибка? Нет, на самом деле в этом случае конструктор будет создан автоматически. Вот такой: - - Book() {} - - Автоматически-сгенерированный конструктор по умолчанию ничего не делает. - Тем не менее, перед вызовом этого конструктора, компилятор должен вызвать конструктор по умолчанию для всех полей класса, - у которых есть конструктор по умолчанию. - В этом случае, при создании объекта класса Book с помощью конструктора по умолчанию, будет вызван конструктор по умолчанию класса String. - - - - Аналогично, автоматически сгенерируется деструктор по умолчанию, вот такой: - - ~Book() {} - - Он пустой, но нужно помнить, что после вызова деструктора класса, автоматически вызываются деструкторы для все его полей (у которых есть деструкторы) - В этом случае, после вызова деструктора класса Book вызовется деструктор класса String. - - - - - - Задачи: - - 1) Скомпилируйте программу, запустите и убедитесь, что в этом примере вызываются - конструктор по умолчанию и деструктор класса String. -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/3default_methods/01special_methods.cpp b/seminar02_encapsulation/classroom_tasks/code/3default_methods/01special_methods.cpp deleted file mode 100644 index 820ab32..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/3default_methods/01special_methods.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* - Особые методы - - Проверим, что компилятор автоматически генерирует конструктор копирования и оператор присваивания. -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - cout << "String Constructor from const char* (" << str << ")" << endl; - - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; ++i) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() - { - cout << "String Default Constructor" << endl; - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char)); - mpData[0] = '\0'; - } - - String(const String& s) - { - cout << "String Copy Constructor (" << s.mpData << ")" << endl; - - size_t i = 0; - mSize = s.mSize; - mCapacity = mSize + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = s.mpData[i]; - mpData[mSize] = '\0'; - } - - ~String() - { - cout << "String Destructor (" << mpData << ")" << endl; - std::free(mpData); - } - - String& operator=(const String& right) - { - cout << "String Assignment Operator (" << right.mpData << ")" << endl; - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - - -class Book -{ -public: - String title; - int pages; - float price; -}; - -void print(Book x) -{ - cout << x.title << " " << x.pages << " " << x.price << endl; -} - -int main() -{ - Book a; - - a.title = "War and Peace"; - a.pages = 1000; - a.price = 1100; - - Book b; - b = a; - print(b); -} - - - -/* - Что напечатает данная программа? - - Разберём код из функции main подробно: - - 1) Вызывается автоматически сгенерированный конструктор по умолчанию в строке: - - Book a; - - При этом перед вызовом этого конструктора вызовется и конструктор класса String поля title. - - - - 2) Полям объекта a присваиваются некоторые значения: - - a.title = "War and Peace"; - a.pages = 1000; - a.price = 1100; - - Интересно отметить, что строка a.title = "War and Peace" работает, несмотря на то, что слева от знака - присваивания стоит объект типа String, а справа от знака присваивания стоит объект типа const char[14]. - Типы не совпадают, но это работает, так как у класса String есть конструктор от const char*. - Таким образом, сначала вызовется этот конструктор и создастся временный объект типа String, а потом - вызовется оператор присваивания между двумя объектами класса String. - После этого временный объект удалится и, соответственно, вызовется его деструктор. - - - - 3) Вызывается автоматически сгенерированный конструктор по умолчанию в строке: - - Book b; - - - - 4) Вызывается автоматически сгенерированный перегруженный оператор присваивания в строке: - - b = a; - - Автоматически сгенерированный оператор присваивания применяет оператор присваивания для каждого поля. - - - - 5) Передача в функцию print осуществляется по значению. Следовательно в строке - - print(b); - - объект b должен быть скопирован внутрь функции. Для этого должен быть вызван конструктор копирования. - Конструктор копирования у класса Book не написан, поэтому компилятор автоматически его сгенерирует. - - Автоматически сгенерированный конструктор копирования копирует каждое поле в соответствующее поле нового объекта. - Если у поля есть конструктор копирования (как например у класса String), то вызывается конструктор копирования этого поля. - Если у поля нет конструктора копирования (как например у int или float), то поле просто копируется побайтово. - - - 6) Выходим из функции print и вызываем деструктор для объекта x. - - 7) Выходим из функции main и вызываем деструкторы для объектов a и b. -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/3default_methods/02default_constructor_remark.cpp b/seminar02_encapsulation/classroom_tasks/code/3default_methods/02default_constructor_remark.cpp deleted file mode 100644 index ca9eb59..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/3default_methods/02default_constructor_remark.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* - Замечание по поводу автоматической генерации конструктора по умолчанию -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - cout << "String Constructor from const char* (" << str << ")" << endl; - - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; ++i) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() - { - cout << "String Default Constructor" << endl; - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char)); - mpData[0] = '\0'; - } - - String(const String& s) - { - cout << "String Copy Constructor (" << s.mpData << ")" << endl; - - size_t i = 0; - mSize = s.mSize; - mCapacity = mSize + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = s.mpData[i]; - mpData[mSize] = '\0'; - } - - ~String() - { - cout << "String Destructor (" << mpData << ")" << endl; - std::free(mpData); - } - - String& operator=(const String& right) - { - cout << "String Assignment Operator (" << right.mpData << ")" << endl; - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - - -class Book -{ -public: - String title; - int pages; - float price; - - Book(const String& aTitle, int aPages, float aPrice) - { - title = aTitle; - pages = aPages; - price = aPrice; - } -}; - - -int main() -{ - Book a; -} - - - -/* - Конструктор по умолчанию не генерируется автоматически если у класса написан хотя бы один конструктор (любой). - Например, в этом пример у класса Book написан один конструктор: - - Book(const String& aTitle, int aPages, float aPrice) - - Поэтому в данном случае конструктор по умочанию автоматически генерироваться не будет. - - - - В строке Book a; должен быть вызван конструктор по умолчанию. - Но у класса Book такого конструктора нет и автоматически он не был создан. Поэтому эта строка приведёт к ошибке. - - - - Но конструктор копирования, оператор присваивания и деструктор автоматически генерироваться будут. - - - Задача: - - Исправьте ошибку, написав конструктор по умолчанию самостоятельно. -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/3default_methods/03delete_keyword.cpp b/seminar02_encapsulation/classroom_tasks/code/3default_methods/03delete_keyword.cpp deleted file mode 100644 index 03916df..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/3default_methods/03delete_keyword.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* - Удалённые методы -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - cout << "String Constructor from const char* (" << str << ")" << endl; - - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; ++i) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() - { - cout << "String Default Constructor" << endl; - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char)); - mpData[0] = '\0'; - } - - String(const String& s) - { - cout << "String Copy Constructor (" << s.mpData << ")" << endl; - - size_t i = 0; - mSize = s.mSize; - mCapacity = mSize + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = s.mpData[i]; - mpData[mSize] = '\0'; - } - - ~String() - { - cout << "String Destructor (" << mpData << ")" << endl; - std::free(mpData); - } - - String& operator=(const String& right) - { - cout << "String Assignment Operator (" << right.mpData << ")" << endl; - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - - -class Book -{ -public: - String title; - int pages; - float price; - - Book() {}; - - Book(const String& aTitle, int aPages, float aPrice) - { - title = aTitle; - pages = aPages; - price = aPrice; - } - - Book(const Book& b) = delete; -}; - - -int main() -{ - Book a; - - Book b = a; -} - - - -/* - Если же вы не хотите создавать какой-либо метод и не хотите чтобы он создавался автоматически, - то его можно удалить с помощью ключевого слова delete. - - - Например, в этом примере у класса Book удалён конструктор копирования вот так: - - Book(const Book& b) = delete; - - Это означает, что конструктор копирования не создастся автоматически. - Поэтому в строке: - - Book b = a; - - произойдёт ошибка компиляции. - - - - Задача: - - 1) Можно ли передать объект класса с удалённым конструктором копирования в функцию по значению? - - Например, если есть функция: - - void print(Book b) - { - cout << b.title << " "<< b.pages << " " << b.price << endl; - } - - Можно ли туда передать что-нибудь? - -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/3default_methods/04implicit_cast_constructor.cpp b/seminar02_encapsulation/classroom_tasks/code/3default_methods/04implicit_cast_constructor.cpp deleted file mode 100644 index 7d42352..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/3default_methods/04implicit_cast_constructor.cpp +++ /dev/null @@ -1,188 +0,0 @@ -/* - Неявное приведение типа с помощью конструктора от одного параметра. -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* s) - { - cout << "String Constructor from const char* (" << s << ")" << endl; - - size_t i = 0; - while (s[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; s[i]; ++i) - mpData[i] = s[i]; - mpData[mSize] = '\0'; - } - - String() - { - cout << "String Default Constructor" << endl; - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char)); - mpData[0] = '\0'; - } - - String(const String& s) - { - cout << "String Copy Constructor (" << s.mpData << ")" << endl; - - size_t i = 0; - mSize = s.mSize; - mCapacity = mSize + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = s.mpData[i]; - mpData[mSize] = '\0'; - } - - ~String() - { - cout << "String Destructor (" << mpData << ")" << endl; - std::free(mpData); - } - - String& operator=(const String& right) - { - cout << "String Assignment Operator (" << right.mpData << ")" << endl; - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - - -void print(String s) -{ - cout << s << endl; -} - - -int main() -{ - String a; - a = "Dog"; - - print("Mouse"); -} - - - -/* - Одна из скрытых вещей, где используются конструкторы, это для неявного приведения типов. - - Рассмотрим следующие строки: - - String a; - a = "Dog"; - - Во второй строке должен вызваться оператор присваивания. - Слева от оператора присваивания стоит объект типа String, а справа от оператора присваивания стоит объект типа const char[4]. - Поэтому должен вызваться метод operator=(const char* s) класса String. (при передаче в функцию массив автоматически конвертируется в указатель) - Но такого метода в классе String нет. Что же тогда будет сделано? - - В этом случае будет сделано следующее: - - 1) Будет создан временный объект типа String с использованием конструтора String(const char* s). - 2) Будет вызван оператор присваивания operator=(const String& s). Объекту a присвоится временный объект. - 3) Временный объект будет уничтожен, при этом вызовется деструктор класса String. - - - - - Рассмотрим строку: - - print("Mouse"); - - Функция print должна принимать объект типа String, но на вход ей приходит объект типа const char[6]. - Что будет сделано в этом случае? - И в этом случае всё сработает, так как объект s функции print будет создан с помощью конструктора класса String от const char*. - - - - Таким образом конструктор от одного аргумента автоматически используется для неявного приведения одного типа в другой. - - - - Задачи: - - 1) Что если мы напишем конструктор класса String от числа типа int. - Этот конструктор будет принимать число n и создавать строку, состоящую из n символов 'a' - - - String(int n) - { - cout << "String Constructor from int (" << n << ")" << endl; - - mSize = n; - mCapacity = mSize + 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - for (size_t i = 0; i < mSize; ++i) - mpData[i] = 'a'; - mpData[mSize] = '\0'; - } - - - - Будет ли этот конструктор использоваться для неявного приведения чисел типа int в строки типа String? - Например, будет ли работать следующий код: - - String b; - b = 5; - - (b будет строкой состоящей из 5 символов 'a' ?) - - - print(10); - - (напечатает строку, состоящую из 10 символов 'a') -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/3default_methods/05explicit.cpp b/seminar02_encapsulation/classroom_tasks/code/3default_methods/05explicit.cpp deleted file mode 100644 index ff73301..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/3default_methods/05explicit.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* - Ключевое слово explicit. -*/ - -#include -#include -using std::cout, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - explicit String(const char* s) - { - cout << "String Constructor from const char* (" << s << ")" << endl; - - size_t i = 0; - while (s[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; s[i]; ++i) - mpData[i] = s[i]; - mpData[mSize] = '\0'; - } - - explicit String(int n) - { - cout << "String Constructor from int (" << n << ")" << endl; - - mSize = n; - mCapacity = mSize + 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - for (size_t i = 0; i < mSize; ++i) - mpData[i] = 'a'; - mpData[mSize] = '\0'; - } - - String() - { - cout << "String Default Constructor" << endl; - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char)); - mpData[0] = '\0'; - } - - String(const String& s) - { - cout << "String Copy Constructor (" << s.mpData << ")" << endl; - - size_t i = 0; - mSize = s.mSize; - mCapacity = mSize + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = s.mpData[i]; - mpData[mSize] = '\0'; - } - - ~String() - { - cout << "String Destructor (" << mpData << ")" << endl; - std::free(mpData); - } - - String& operator=(const String& right) - { - cout << "String Assignment Operator (" << right.mpData << ")" << endl; - if (this == &right) - return *this; - - - mSize = right.mSize; - mCapacity = right.mCapacity; - - std::free(mpData); - mpData = (char*)malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - -std::ostream& operator<<(std::ostream& left, const String& right) -{ - left << right.cStr(); - return left; -} - - - -void print(String s) -{ - cout << s << endl; -} - - -int main() -{ - String a; - a = "Dog"; - - print("Mouse"); - print(10); -} - - - -/* - Иногда всё-таки не хочется, чтобы конструкторы использовались для неявного приведения типов. - Ведь такое приведение типов может произойти там, где мы этого не хотим. - - Чтобы конструктор не использовался для неявного приведения, его нужно пометить с помощью ключевого слова explicit. - В этом примере, конструкторы String(const char* s) и String(int n) помечены как explicit. - Поэтому эти конструкторы не будут использоваться для неявного приведения типов и код в функции main выдаст ошибку. - Но эти конструкторы всё равно можно вызывать явно, вот так: - - String a; - a = String("Dog"); - - print(String("Mouse")); - print(String(10)); -*/ \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/00point/main.cpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/00point/main.cpp deleted file mode 100644 index 9921eee..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/00point/main.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - Раздельная компиляция. - - В этой части мы вынесем весь код, связанный с нашим классом Point в отдельные файлы. - А также скомпилируем отдельно код, относящийся к нашему классу Point. - - Это будет проделано в следующий примерах, а пока тут просто лежит код - класса Point из предыдущих частей. -*/ - - -#include -#include -#include -using std::cout, std::endl; - - -struct Point -{ - float x, y; - - Point operator+(Point b) const - { - Point result = {x + b.x, y + b.y}; - return result; - } - - float norm() const - { - return std::sqrt(x * x + y * y); - } - - Point operator*(float k) const - { - Point result = {k * x, k * y}; - return result; - } - - void normalize() - { - float normv = norm(); - x /= normv; - y /= normv; - } -}; - -std::ostream& operator<<(std::ostream& out, Point a) -{ - out << std::setprecision(2) << "(" << a.x << ", " << a.y << ")"; - return out; -} - - -int main() -{ - Point a = {7.2, 3.1}; - cout << a.norm() << endl; -} - - - - diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/01point_separate_methods/main.cpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/01point_separate_methods/main.cpp deleted file mode 100644 index d55993e..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/01point_separate_methods/main.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - Вынос определений методов вне класса. - - Методы внутри класса можно только объявить, а определить их можно вне класса. - Например, метод norm объявлен внутри класса: - - float norm() const; - - а определён вне класса: - - float Point::norm() const - { - return std::sqrt(x * x + y * y); - } - - - Чтобы компилятор понимал к какому классу относится тот или иной метод, - к его имени вне класса нужно добавить название класса и два двоеточия. - Поэтому метод norm вне класса Point называется как Point::norm. - -*/ - - -#include -#include -#include -using std::cout, std::endl; - - -struct Point -{ - float x, y; - - Point operator+(Point b) const; - float norm() const; - Point operator*(float k) const; - void normalize(); -}; - - -Point Point::operator+(Point b) const -{ - Point result = {x + b.x, y + b.y}; - return result; -} - -float Point::norm() const -{ - return std::sqrt(x * x + y * y); -} - -Point Point::operator*(float k) const -{ - Point result = {k * x, k * y}; - return result; -} - -void Point::normalize() -{ - float normv = norm(); - x /= normv; - y /= normv; -} - - -std::ostream& operator<<(std::ostream& out, Point a) -{ - out << std::setprecision(2) << "(" << a.x << ", " << a.y << ")"; - return out; -} - - -int main() -{ - Point a = {7.2, 3.1}; - cout << a.norm() << endl; -} - - - - diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/02point_headers/main.cpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/02point_headers/main.cpp deleted file mode 100644 index 1becf58..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/02point_headers/main.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - Перенос кода в заголовочный файл - - В этом примере мы перенесли весь код, связанный с классом Point в отдельный файл point.hpp. - Файл point.hpp подключается к файлу main.cpp с помощью директивы #include в строке: - - #include "point.hpp" - - На самом деле директива #include делает очень простую вещь: она просто берёт всё содержимое - передаваемого ей файла и вставляет это содержимое на место директивы. - То есть в этом примере за место #include "point.hpp" подставится всё содержимое файла point.hpp. - - Так как директива #include уже сама вставила файл point.hpp в файл main.cpp, то дополнительно - указывать файл point.hpp при компиляции не нужно. Скомпилировать этот пример можно так: - - g++ main.cpp - - - Стандартные библиотеки типа iostream подключаются так же. То есть где-то в системе, в какой-то папке - хранится стандартная библиотека C++ и, соответственно, есть файл под название iostream (без расширения). - Этот файл и подставляется за место строки #include . - Чтобы посмотреть в каких папках компилятор ищет файлы стандартной библиотеки можно скомпилировать программу так: - - g++ -v main.cpp - - Он напечатает множество информации о компиляции, в числе прочего пути где происходит поиск при исполнении #include. - Вы могли заметить, что стандартные библиотеки в директиве #include пишутся в треугольных скобочках, а нашу - библиотеку point.hpp мы написали в двойных кавычках. В чём разница между этими вариантами? - На самом деле разница лишь в том, в каких папках компилятор ищет данные файлы. - Если мы пишем библиотеку в треугольных скобках, то компилятор ищет её в папках стандартной библиотеки. - Если мы пишем библиотеку в кавычках, то компилятор ищет её в папках текущей директории. - - - - Защита от двойного включения - - Используя директивы #include, очень легко включить один и тот же файл 2 и более раз. - Например, в этом примере файл iostream включается 2 раза: один раз непосредственно в файле main.cpp, а второй раз - он включится после того, как включиться файл point.hpp. Внутри файла point.hpp тоже есть #include . - Если не предпринимать никаких действий, то произойдёт ошибка, так как одинаковые функции и классы - будут повторяться в программе несколько раз. - - Чтобы защититься от этой проблемы нужно в начале заголовочного файла написать директиву - - #pragma once - - Таким образом компилятор будет понимать, что вы не хотите включать файл более одного раза и включит только одну копию файла. - Эта директива была использовани и в файле point.hpp. -*/ - - -#include -#include "point.hpp" - -using std::cout, std::endl; - -int main() -{ - Point a = {7.2, 3.1}; - cout << a.norm() << endl; -} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/02point_headers/point.hpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/02point_headers/point.hpp deleted file mode 100644 index f92184c..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/02point_headers/point.hpp +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once -#include -#include -#include - -struct Point -{ - float x, y; - - Point operator+(Point b) const - { - Point result = {x + b.x, y + b.y}; - return result; - } - - float norm() const - { - return std::sqrt(x * x + y * y); - } - - Point operator*(float k) const - { - Point result = {k * x, k * y}; - return result; - } - - void normalize() - { - float normv = norm(); - x /= normv; - y /= normv; - } -}; - -std::ostream& operator<<(std::ostream& out, Point a) -{ - out << std::setprecision(2) << "(" << a.x << ", " << a.y << ")"; - return out; -} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/03point_headers/main.cpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/03point_headers/main.cpp deleted file mode 100644 index 3d5c875..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/03point_headers/main.cpp +++ /dev/null @@ -1,17 +0,0 @@ -/* - Всё что относится к классу Point мы перенесли в отдельный файл point.hpp. - А также мы разделили объявления и определения методов в файле point.hpp. -*/ - -#include -#include -#include -#include "point.hpp" - -using std::cout, std::endl; - -int main() -{ - Point a = {7.2, 3.1}; - cout << a.norm() << endl; -} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/03point_headers/point.hpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/03point_headers/point.hpp deleted file mode 100644 index e60bfbe..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/03point_headers/point.hpp +++ /dev/null @@ -1,45 +0,0 @@ -#pragma once -#include - - -struct Point -{ - float x, y; - - Point operator+(Point b) const; - float norm() const; - Point operator*(float k) const; - void normalize(); -}; - - -Point Point::operator+(Point b) const -{ - Point result = {x + b.x, y + b.y}; - return result; -} - -float Point::norm() const -{ - return std::sqrt(x * x + y * y); -} - -Point Point::operator*(float k) const -{ - Point result = {k * x, k * y}; - return result; -} - -void Point::normalize() -{ - float normv = norm(); - x /= normv; - y /= normv; -} - - -std::ostream& operator<<(std::ostream& out, Point a) -{ - out << std::setprecision(2) << "(" << a.x << ", " << a.y << ")"; - return out; -} diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/04point_separate_compilation/main.cpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/04point_separate_compilation/main.cpp deleted file mode 100644 index 926aecf..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/04point_separate_compilation/main.cpp +++ /dev/null @@ -1,40 +0,0 @@ -/* - Раздельная компиляция - - Теперь мы разделим объявления и определения всех методов класса Point. - Все объявления класса Point поместим в файл point.hpp, а определения методов в файл point.cpp. - Таким образом у нас получилось 2 компилируемых файла: main.cpp и point.cpp и 1 заголовочный файл point.hpp. - - При этом заголовочный файл point.hpp должен подключаться везде, где используется класс Point. - То есть в данном случае он должен подключаться и в файл main.cpp и в файл point.cpp. - - - Для компиляции программы нужно указать компилятору на все компилируемые файлы вот так: - - g++ main.cpp point.cpp - - Если это не сделать и скомпилировать только файл main.cpp, то возникнет ошибка undefined reference to norm(). - Грубо говоря программа будет знать, что есть класс Point и знать его методы (так как это всё описано в point.hpp), - но любые попытки вызвать эти методы будут приводить к ошибке, так как они не были скомпилированы. - - - Преемущество раздельной компиляции заключается в том, что компилировать разные .cpp файлы можно поотдельности. - Представьте, что у вас огромный проект, содержащий тысячи файлов и миллионы строк кода. Такой проект может компилироваться часами. - Теперь вы сделали небольшое изменение в одном файле этого проекта. Если бы нельзя было бы компилировать файлы поотдельности, - то после любого изменения вам бы пришлось компилировать весь проект заново и ждать часы пока компиляция закончится. - К счастью, .cpp файлы можно компилировать поотдельности и, если вы сделали изменение в одном файле, то скомпилировать - потребуется только тот файл, который вы изменили. -*/ - - - -#include -#include "point.hpp" - -using std::cout, std::endl; - -int main() -{ - Point a = {7.2, 3.1}; - cout << a.norm() << endl; -} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/04point_separate_compilation/point.cpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/04point_separate_compilation/point.cpp deleted file mode 100644 index 143dd83..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/04point_separate_compilation/point.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include -#include -#include -#include "point.hpp" - -Point Point::operator+(Point b) const -{ - Point result = {x + b.x, y + b.y}; - return result; -} - -float Point::norm() const -{ - return std::sqrt(x * x + y * y); -} - -Point Point::operator*(float k) const -{ - Point result = {k * x, k * y}; - return result; -} - -void Point::normalize() -{ - float normv = norm(); - x /= normv; - y /= normv; -} - - -std::ostream& operator<<(std::ostream& out, Point a) -{ - out << std::setprecision(2) << "(" << a.x << ", " << a.y << ")"; - return out; -} diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/04point_separate_compilation/point.hpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/04point_separate_compilation/point.hpp deleted file mode 100644 index 1e48146..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/04point_separate_compilation/point.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include - - -struct Point -{ - float x, y; - - Point operator+(Point b) const; - float norm() const; - Point operator*(float k) const; - void normalize(); -}; - -std::ostream& operator<<(std::ostream& out, Point a); diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/05point_namespace/main.cpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/05point_namespace/main.cpp deleted file mode 100644 index d248d06..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/05point_namespace/main.cpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - Пространства имён - - - Имя Point достаточно распространённое и есть очень большая вероятность того, что при подключении нескольких библиотек - в некоторых из них тоже будет класс с именем Point. Конечно, если ничего не предпринять, это приведёт к ошибке. - - Чтобы избежать ошибок, связанных с конфликтами имён, положим весь код нашего класса Point в пространство имён mipt. - Для этого обернём наш код в файлах point.hpp и point.cpp - - namespace mipt - { - ... - } - - Теперь наш класс Point будет лежать в пространстве имён mipt. - Для его использования вне пространства имён mipt нужно писать mipt::Point (ну либо использовать using mipt::Point;) -*/ - - -#include -#include "point.hpp" - -using std::cout, std::endl; - -int main() -{ - mipt::Point a = {7.2, 3.1}; - cout << a.norm() << endl; -} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/05point_namespace/point.cpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/05point_namespace/point.cpp deleted file mode 100644 index 7a3ade1..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/05point_namespace/point.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include -#include -#include -#include "point.hpp" - -namespace mipt -{ - -Point Point::operator+(Point b) const -{ - Point result = {x + b.x, y + b.y}; - return result; -} - -float Point::norm() const -{ - return std::sqrt(x * x + y * y); -} - -Point Point::operator*(float k) const -{ - Point result = {k * x, k * y}; - return result; -} - -void Point::normalize() -{ - float normv = norm(); - x /= normv; - y /= normv; -} - - -std::ostream& operator<<(std::ostream& out, Point a) -{ - out << std::setprecision(2) << "(" << a.x << ", " << a.y << ")"; - return out; -} - -} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/05point_namespace/point.hpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/05point_namespace/point.hpp deleted file mode 100644 index 4f0944a..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/05point_namespace/point.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once -#include - - -namespace mipt -{ - -struct Point -{ - float x, y; - - Point operator+(Point b) const; - float norm() const; - Point operator*(float k) const; - void normalize(); -}; - -std::ostream& operator<<(std::ostream& out, Point a); - -} diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string/main.cpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string/main.cpp deleted file mode 100644 index 414a000..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string/main.cpp +++ /dev/null @@ -1,265 +0,0 @@ -/* - В данной программе содержится класс String, написанный нами в одной из предыдущих частей. - - Задачи: - - 1) Вынесите класс String в отдельный заголовочный файл string.hpp и скомпилируйте программу. - - - 2) Вынесите объявления методов класса String в заголовочный файл string.hpp, а определения - методов в компилируемый файл string.cpp. Скомпилируйте программу. - - - 3) Вынесите объявления методов класса String в заголовочный файл string.hpp, а определения - методов в компилируемый файл string.cpp. А также поместите весь код класса String в пространство имён mipt. - Скомпилируйте программу. -*/ - - -#include -#include - - -class String -{ -private: - - std::size_t mSize; - std::size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - std::size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (std::size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - String(std::size_t n, char a) - { - mSize = n; - mCapacity = n + 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (std::size_t i = 0; i < mSize; ++i) - mpData[i] = a; - mpData[mSize] = '\0'; - } - - ~String() - { - std::free(mpData); - } - - void reserve(std::size_t capacity) - { - if (capacity <= mCapacity) - return; - - mCapacity = capacity; - char* newData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (std::size_t i = 0; i < mSize; ++i) - newData[i] = mpData[i]; - newData[mSize] = '\0'; - - std::free(mpData); - mpData = newData; - } - - - void resize(std::size_t size) - { - reserve(size + 1); - mSize = size; - mpData[mSize] = '\0'; - } - - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - mSize = right.mSize; - resize(mSize); - - for (std::size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - - String operator+(const String& b) - { - String result; - result.resize(mSize + b.mSize); - - for (std::size_t i = 0; i < mSize; ++i) - result.mpData[i] = mpData[i]; - - for (std::size_t i = 0; i < b.mSize; ++i) - result.mpData[mSize + i] = b.mpData[i]; - - result.mpData[result.mSize] = '\0'; - - return result; - } - - String& operator+=(const String& right) - { - *this = *this + right; - return *this; - } - - bool operator==(const String& right) const - { - if (mSize != right.mSize) - return false; - - std::size_t i = 0; - while (i < mSize && mpData[i] == right.mpData[i]) - i++; - - return i == mSize; - } - - bool operator<(const String& right) const - { - std::size_t i = 0; - while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) - i++; - - return mpData[i] < right.mpData[i]; - } - - bool operator<=(const String& right) const - { - std::size_t i = 0; - while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) - i++; - - return mpData[i] <= right.mpData[i]; - } - - bool operator!=(const String& right) const - { - return !(*this == right); - } - - bool operator>(const String& right) const - { - return !(*this <= right); - } - - bool operator>=(const String& right) const - { - return !(*this < right); - } - - char& operator[](std::size_t i) - { - return mpData[i]; - } - - char& at(std::size_t i) - { - if (i >= mSize) - { - std::cout << "Error! Index is out of bounds." << std::endl; - std::exit(1); - } - return mpData[i]; - } - - void clear() - { - std::free(mpData); - - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - mpData[0] = '\0'; - } - - void addCharacter(char c) - { - if (mSize + 1 == mCapacity) - reserve(2 * mCapacity); - - mpData[mSize] = c; - resize(mSize + 1); - } - - - std::size_t getSize() const {return mSize;} - std::size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& out, const String& s) -{ - out << s.cStr(); - return out; -} - -std::istream& operator>>(std::istream& in, String& s) -{ - s.clear(); - while (true) - { - char x = in.get(); - if (x == ' ' || x == '\n' || x == '\t') - break; - s.addCharacter(x); - } - return in; -} - - -int main() -{ - String a = "Mouse"; - String b; - std::cin >> b; - String c = b; - - if (a + c == "MouseLion") - std::cout << "Yes" << std::endl; - else - std::cout << "No" << std::endl; - - - if (a > "Mice") - std::cout << "Yes" << std::endl; - else - std::cout << "No" << std::endl; - - - c[0] = 'P'; - std::cout << c << std::endl; - - c += a; - std::cout << c << std::endl; - - c = c + String(10, 'q'); - std::cout << c << std::endl; -} - - - diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution1/main.cpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution1/main.cpp deleted file mode 100644 index 3a98561..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution1/main.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include -#include -#include "string.hpp" - -using std::cout, std::cin, std::endl; - -int main() -{ - String a = "Mouse"; - String b; - cin >> b; - String c = b; - - if (a + c == "MouseLion") - cout << "Yes" << endl; - else - cout << "No" << endl; - - - if (a > "Mice") - cout << "Yes" << endl; - else - cout << "No" << endl; - - - c[0] = 'P'; - cout << c << endl; - - c += a; - cout << c << endl; - - c = c + String(10, 'q'); - cout << c << endl; -} - - - diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution1/string.hpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution1/string.hpp deleted file mode 100644 index c082dd6..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution1/string.hpp +++ /dev/null @@ -1,214 +0,0 @@ -#include -#include - - -class String -{ -private: - - std::size_t mSize; - std::size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - std::size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (std::size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - String(std::size_t n, char a) - { - mSize = n; - mCapacity = n + 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (std::size_t i = 0; i < mSize; ++i) - mpData[i] = a; - mpData[mSize] = '\0'; - } - - ~String() - { - std::free(mpData); - } - - void reserve(std::size_t capacity) - { - if (capacity <= mCapacity) - return; - - mCapacity = capacity; - char* newData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (std::size_t i = 0; i < mSize; ++i) - newData[i] = mpData[i]; - newData[mSize] = '\0'; - - std::free(mpData); - mpData = newData; - } - - - void resize(std::size_t size) - { - reserve(size + 1); - mSize = size; - mpData[mSize] = '\0'; - } - - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - mSize = right.mSize; - resize(mSize); - - for (std::size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - - String operator+(const String& b) - { - String result; - result.resize(mSize + b.mSize); - - for (std::size_t i = 0; i < mSize; ++i) - result.mpData[i] = mpData[i]; - - for (std::size_t i = 0; i < b.mSize; ++i) - result.mpData[mSize + i] = b.mpData[i]; - - result.mpData[result.mSize] = '\0'; - - return result; - } - - String& operator+=(const String& right) - { - *this = *this + right; - return *this; - } - - bool operator==(const String& right) const - { - if (mSize != right.mSize) - return false; - - std::size_t i = 0; - while (i < mSize && mpData[i] == right.mpData[i]) - i++; - - return i == mSize; - } - - bool operator<(const String& right) const - { - std::size_t i = 0; - while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) - i++; - - return mpData[i] < right.mpData[i]; - } - - bool operator<=(const String& right) const - { - std::size_t i = 0; - while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) - i++; - - return mpData[i] <= right.mpData[i]; - } - - bool operator!=(const String& right) const - { - return !(*this == right); - } - - bool operator>(const String& right) const - { - return !(*this <= right); - } - - bool operator>=(const String& right) const - { - return !(*this < right); - } - - char& operator[](std::size_t i) - { - return mpData[i]; - } - - char& at(std::size_t i) - { - if (i >= mSize) - { - std::cout << "Error! Index is out of bounds." << std::endl; - std::exit(1); - } - return mpData[i]; - } - - void clear() - { - std::free(mpData); - - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - mpData[0] = '\0'; - } - - void addCharacter(char c) - { - if (mSize + 1 == mCapacity) - reserve(2 * mCapacity); - - mpData[mSize] = c; - resize(mSize + 1); - } - - - std::size_t getSize() const {return mSize;} - std::size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& out, const String& s) -{ - out << s.cStr(); - return out; -} - -std::istream& operator>>(std::istream& in, String& s) -{ - s.clear(); - while (true) - { - char x = in.get(); - if (x == ' ' || x == '\n' || x == '\t') - break; - s.addCharacter(x); - } - return in; -} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution2/main.cpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution2/main.cpp deleted file mode 100644 index 19996c2..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution2/main.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - Компиляция: - - g++ main.cpp string.cpp - -*/ - -#include -#include "string.hpp" -using std::cout, std::cin, std::endl; - -int main() -{ - String a = "Mouse"; - String b; - cin >> b; - String c = b; - - if (a + c == "MouseLion") - cout << "Yes" << endl; - else - cout << "No" << endl; - - - if (a > "Mice") - cout << "Yes" << endl; - else - cout << "No" << endl; - - - c[0] = 'P'; - cout << c << endl; - - c += a; - cout << c << endl; - - c = c + String(10, 'q'); - cout << c << endl; -} diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution2/string.cpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution2/string.cpp deleted file mode 100644 index f685590..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution2/string.cpp +++ /dev/null @@ -1,204 +0,0 @@ -#include -#include -#include "string.hpp" - - -String::String(const char* str) -{ - std::size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (std::size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; -} - -String::String() : String("") {} -String::String(const String& s) : String(s.cStr()) {} - -String::String(std::size_t n, char a) -{ - mSize = n; - mCapacity = n + 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (std::size_t i = 0; i < mSize; ++i) - mpData[i] = a; - mpData[mSize] = '\0'; -} - -String::~String() -{ - std::free(mpData); -} - -void String::reserve(std::size_t capacity) -{ - if (capacity <= mCapacity) - return; - - mCapacity = capacity; - char* newData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (std::size_t i = 0; i < mSize; ++i) - newData[i] = mpData[i]; - newData[mSize] = '\0'; - - std::free(mpData); - mpData = newData; -} - - -void String::resize(std::size_t size) -{ - reserve(size + 1); - mSize = size; - mpData[mSize] = '\0'; -} - - -String& String::operator=(const String& right) -{ - if (this == &right) - return *this; - - mSize = right.mSize; - resize(mSize); - - for (std::size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; -} - - -String String::operator+(const String& b) -{ - String result; - result.resize(mSize + b.mSize); - - for (std::size_t i = 0; i < mSize; ++i) - result.mpData[i] = mpData[i]; - - for (std::size_t i = 0; i < b.mSize; ++i) - result.mpData[mSize + i] = b.mpData[i]; - - result.mpData[result.mSize] = '\0'; - - return result; -} - -String& String::operator+=(const String& right) -{ - *this = *this + right; - return *this; -} - -bool String::operator==(const String& right) const -{ - if (mSize != right.mSize) - return false; - - std::size_t i = 0; - while (i < mSize && mpData[i] == right.mpData[i]) - i++; - - return i == mSize; -} - -bool String::operator<(const String& right) const -{ - std::size_t i = 0; - while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) - i++; - - return mpData[i] < right.mpData[i]; -} - -bool String::operator<=(const String& right) const -{ - std::size_t i = 0; - while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) - i++; - - return mpData[i] <= right.mpData[i]; -} - -bool String::operator!=(const String& right) const -{ - return !(*this == right); -} - -bool String::operator>(const String& right) const -{ - return !(*this <= right); -} - -bool String::operator>=(const String& right) const -{ - return !(*this < right); -} - -char& String::operator[](std::size_t i) -{ - return mpData[i]; -} - -char& String::at(std::size_t i) -{ - if (i >= mSize) - { - std::cout << "Error! Index is out of bounds." << std::endl; - std::exit(1); - } - return mpData[i]; -} - -void String::clear() -{ - std::free(mpData); - - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - mpData[0] = '\0'; -} - -void String::addCharacter(char c) -{ - if (mSize + 1 == mCapacity) - reserve(2 * mCapacity); - - mpData[mSize] = c; - resize(mSize + 1); -} - - -std::size_t String::getSize() const {return mSize;} -std::size_t String::getCapacity() const {return mCapacity;} -const char* String::cStr() const {return mpData;} - - -std::ostream& operator<<(std::ostream& out, const String& s) -{ - out << s.cStr(); - return out; -} - -std::istream& operator>>(std::istream& in, String& s) -{ - s.clear(); - while (true) - { - char x = in.get(); - if (x == ' ' || x == '\n' || x == '\t') - break; - s.addCharacter(x); - } - return in; -} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution2/string.hpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution2/string.hpp deleted file mode 100644 index 3f87a04..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution2/string.hpp +++ /dev/null @@ -1,51 +0,0 @@ -#pragma once -#include -#include - - -class String -{ -private: - - std::size_t mSize; - std::size_t mCapacity; - char* mpData; - -public: - - String(const char* str); - - String(); - String(const String& s); - - String(std::size_t n, char a); - ~String(); - - void reserve(std::size_t capacity); - void resize(std::size_t size); - - String& operator=(const String& right); - String operator+(const String& b); - String& operator+=(const String& right); - - bool operator==(const String& right) const; - bool operator<(const String& right) const; - bool operator<=(const String& right) const; - bool operator!=(const String& right) const; - bool operator>(const String& right) const; - bool operator>=(const String& right) const; - - char& operator[](std::size_t i); - char& at(std::size_t i); - - void clear(); - void addCharacter(char c); - - std::size_t getSize() const; - std::size_t getCapacity() const; - const char* cStr() const; -}; - - -std::ostream& operator<<(std::ostream& out, const String& s); -std::istream& operator>>(std::istream& in, String& s); diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution3/main.cpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution3/main.cpp deleted file mode 100644 index ccd3472..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution3/main.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include -#include "string.hpp" -using std::cout, std::cin, std::endl; - -int main() -{ - mipt::String a = "Mouse"; - mipt::String b; - cin >> b; - mipt::String c = b; - - if (a + c == "MouseLion") - cout << "Yes" << endl; - else - cout << "No" << endl; - - - if (a > "Mice") - cout << "Yes" << endl; - else - cout << "No" << endl; - - - c[0] = 'P'; - cout << c << endl; - - c += a; - cout << c << endl; - - c = c + mipt::String(10, 'q'); - cout << c << endl; -} diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution3/string.cpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution3/string.cpp deleted file mode 100644 index bdf2abf..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution3/string.cpp +++ /dev/null @@ -1,207 +0,0 @@ -#include -#include -#include "string.hpp" - -namespace mipt { - -String::String(const char* str) -{ - std::size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (std::size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; -} - -String::String() : String("") {} -String::String(const String& s) : String(s.cStr()) {} - -String::String(std::size_t n, char a) -{ - mSize = n; - mCapacity = n + 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (std::size_t i = 0; i < mSize; ++i) - mpData[i] = a; - mpData[mSize] = '\0'; -} - -String::~String() -{ - std::free(mpData); -} - -void String::reserve(std::size_t capacity) -{ - if (capacity <= mCapacity) - return; - - mCapacity = capacity; - char* newData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (std::size_t i = 0; i < mSize; ++i) - newData[i] = mpData[i]; - newData[mSize] = '\0'; - - std::free(mpData); - mpData = newData; -} - - -void String::resize(std::size_t size) -{ - reserve(size + 1); - mSize = size; - mpData[mSize] = '\0'; -} - - -String& String::operator=(const String& right) -{ - if (this == &right) - return *this; - - mSize = right.mSize; - resize(mSize); - - for (std::size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; -} - - -String String::operator+(const String& b) -{ - String result; - result.resize(mSize + b.mSize); - - for (std::size_t i = 0; i < mSize; ++i) - result.mpData[i] = mpData[i]; - - for (std::size_t i = 0; i < b.mSize; ++i) - result.mpData[mSize + i] = b.mpData[i]; - - result.mpData[result.mSize] = '\0'; - - return result; -} - -String& String::operator+=(const String& right) -{ - *this = *this + right; - return *this; -} - -bool String::operator==(const String& right) const -{ - if (mSize != right.mSize) - return false; - - std::size_t i = 0; - while (i < mSize && mpData[i] == right.mpData[i]) - i++; - - return i == mSize; -} - -bool String::operator<(const String& right) const -{ - std::size_t i = 0; - while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) - i++; - - return mpData[i] < right.mpData[i]; -} - -bool String::operator<=(const String& right) const -{ - std::size_t i = 0; - while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) - i++; - - return mpData[i] <= right.mpData[i]; -} - -bool String::operator!=(const String& right) const -{ - return !(*this == right); -} - -bool String::operator>(const String& right) const -{ - return !(*this <= right); -} - -bool String::operator>=(const String& right) const -{ - return !(*this < right); -} - -char& String::operator[](std::size_t i) -{ - return mpData[i]; -} - -char& String::at(std::size_t i) -{ - if (i >= mSize) - { - std::cout << "Error! Index is out of bounds." << std::endl; - std::exit(1); - } - return mpData[i]; -} - -void String::clear() -{ - std::free(mpData); - - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - mpData[0] = '\0'; -} - -void String::addCharacter(char c) -{ - if (mSize + 1 == mCapacity) - reserve(2 * mCapacity); - - mpData[mSize] = c; - resize(mSize + 1); -} - - -std::size_t String::getSize() const {return mSize;} -std::size_t String::getCapacity() const {return mCapacity;} -const char* String::cStr() const {return mpData;} - - -std::ostream& operator<<(std::ostream& out, const String& s) -{ - out << s.cStr(); - return out; -} - -std::istream& operator>>(std::istream& in, String& s) -{ - s.clear(); - while (true) - { - char x = in.get(); - if (x == ' ' || x == '\n' || x == '\t') - break; - s.addCharacter(x); - } - return in; -} - -} \ No newline at end of file diff --git a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution3/string.hpp b/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution3/string.hpp deleted file mode 100644 index ca0d683..0000000 --- a/seminar02_encapsulation/classroom_tasks/code/4separate_compilation/06problem_string_solution3/string.hpp +++ /dev/null @@ -1,54 +0,0 @@ -#pragma once -#include -#include - -namespace mipt { - -class String -{ -private: - - std::size_t mSize; - std::size_t mCapacity; - char* mpData; - -public: - - String(const char* str); - - String(); - String(const String& s); - - String(std::size_t n, char a); - ~String(); - - void reserve(std::size_t capacity); - void resize(std::size_t size); - - String& operator=(const String& right); - String operator+(const String& b); - String& operator+=(const String& right); - - bool operator==(const String& right) const; - bool operator<(const String& right) const; - bool operator<=(const String& right) const; - bool operator!=(const String& right) const; - bool operator>(const String& right) const; - bool operator>=(const String& right) const; - - char& operator[](std::size_t i); - char& at(std::size_t i); - - void clear(); - void addCharacter(char c); - - std::size_t getSize() const; - std::size_t getCapacity() const; - const char* cStr() const; -}; - - -std::ostream& operator<<(std::ostream& out, const String& s); -std::istream& operator>>(std::istream& in, String& s); - -} \ No newline at end of file diff --git a/seminar02_encapsulation/homework/homework_encapsulation.tex b/seminar02_encapsulation/homework/homework_encapsulation.tex deleted file mode 100644 index c6e904f..0000000 --- a/seminar02_encapsulation/homework/homework_encapsulation.tex +++ /dev/null @@ -1,202 +0,0 @@ -\documentclass{article} -\usepackage[utf8x]{inputenc} -\usepackage{ucs} -\usepackage{amsmath} -\usepackage{amsfonts} -\usepackage{marvosym} -\usepackage{wasysym} -\usepackage{upgreek} -\usepackage[english,russian]{babel} -\usepackage{graphicx} -\usepackage{float} -\usepackage{textcomp} -\usepackage{hyperref} -\usepackage{geometry} - \geometry{left=2cm} - \geometry{right=1.5cm} - \geometry{top=1cm} - \geometry{bottom=2cm} -\usepackage{tikz} -\usepackage{ccaption} -\usepackage{multicol} -\usepackage{fancyvrb} - -\usepackage{listings} -%\setlength{\columnsep}{1.5cm} -%\setlength{\columnseprule}{0.2pt} - -\usepackage{colortbl,graphicx,tikz} -\definecolor{X}{rgb}{.5,.5,.5} - -\date{} -\begin{document} -\pagenumbering{gobble} - -\lstset{ - language=C++, % choose the language of the code - basicstyle=\linespread{1.1}\ttfamily, - columns=fixed, - fontadjust=true, - basewidth=0.5em, - keywordstyle=\color{blue}\bfseries, - commentstyle=\color{gray}, - stringstyle=\ttfamily\color{orange!50!black}, - showstringspaces=false, - %numbers=false, % where to put the line-numbers - numbersep=5pt, - numberstyle=\tiny\color{black}, - numberfirstline=true, - stepnumber=1, % the step between two line-numbers. - numbersep=10pt, % how far the line-numbers are from the code - backgroundcolor=\color{white}, % choose the background color. You must add \usepackage{color} - showstringspaces=false, % underline spaces within strings - captionpos=b, % sets the caption-position to bottom - breaklines=true, % sets automatic line breaking - breakatwhitespace=true, % sets if automatic breaks should only happen at whitespace - xleftmargin=.2in, - extendedchars=\true, - keepspaces = true, -} -\lstset{literate=% - *{0}{{{\color{red!20!violet}0}}}1 - {1}{{{\color{red!20!violet}1}}}1 - {2}{{{\color{red!20!violet}2}}}1 - {3}{{{\color{red!20!violet}3}}}1 - {4}{{{\color{red!20!violet}4}}}1 - {5}{{{\color{red!20!violet}5}}}1 - {6}{{{\color{red!20!violet}6}}}1 - {7}{{{\color{red!20!violet}7}}}1 - {8}{{{\color{red!20!violet}8}}}1 - {9}{{{\color{red!20!violet}9}}}1 - {~} {$\sim$}{1} -} - -\title{Семинар \#2: Инкапсуляция. Домашнее задание.\vspace{-5ex}}\date{}\maketitle - -\section*{Класс Circle} -Допустим, что мы хотим создать программу, которая будет работать с окружностями (это может быть игра или, например, графический редактор). Для того, чтобы сделать код более понятным и удобным в использовании, мы решили создать класс окружности. Кроме того, мы решили использовать уже ранее написанный класс точки в 2D пространстве (файлы \texttt{point.h} и \texttt{point.cpp}). Создайте класс окружности, который будет включать следующие методы: -\begin{itemize} -\item Конструктор \texttt{Circle(const Point\& acenter, float aradius)}, который будет задавать поля \texttt{center} и \texttt{radius} соответстующими значениями. -\item Конструктор по умолчанию \texttt{Circle()} - задаются значения, соответствующие единичной окружности с центром в начале координат. -\item Конструктор копирования \texttt{Circle(const Circle\& circle)} -\item Сеттеры и геттеры, для полей \texttt{center} и \texttt{radius}. Поле \texttt{radius} нельзя задать отрицательным числом. При попытке задания его отрицательным числом оно должно устанавливаться в значение \texttt{0}. -\item Метод \texttt{float getArea() const}, который будет возвращать площадь поверхности круга. -\item Метод \texttt{float getDistance(const Point\& p) const}, который будет возвращать расстояние от точки \texttt{p}, до ближайшей точки окружности. -\item Метод \texttt{bool isColliding(const Circle\& c) const}, который будет возвращать \texttt{true}, если круг пересекается с кругом \texttt{c}. -\item Метод \texttt{void move(const Point\& p)}, который будет перемещать кружок на вектор \texttt{p}. -\end{itemize} -Весь начальный код содержится в папке \texttt{0circle}. При компиляции нужно указывать все \texttt{.cpp} файлы, которые вы хотите скомпилировать: -\begin{verbatim} -g++ main.cpp point.cpp -\end{verbatim} -\begin{itemize} -\item Создайте файлы \texttt{circle.h} и \texttt{circle.cpp} и перенесите реализацию класса окружности из файла \texttt{main.cpp} в эти файлы. -\end{itemize} - - -\newpage -\section*{Класс Number (большое число)} -Стандартные целочисленные типы данных, такие как \texttt{int} имеют фиксированный небольшой размер. Соответственно значения, которые можно хранить в переменных этих типов ограничены. Типичное максимальное значение \texttt{char} равно $2^7 - 1 = 127$, тип \texttt{int} обычно ограничен $2^{31}-1 = 2147483647$ и даже тип \texttt{unsigned long long} имеет ограничение в $2^{64}-1 = 1.8 * 10^{19}$. Хранить действительно большие числа в этих типах невозможно. В этом задании нужно сделать класс, с помощью которого будет удобно складывать и умножать большие целые положительные числа. Начальный код этого класса содержится в \texttt{1number/number.cpp}. Изучите этот код. - - -\begin{figure}[h!] - \centering - \includegraphics[scale=1]{../images/number1.png} - \caption{Представление числа 12345678 в памяти с помощью нашего класса Number} - \label{fig:nummber1} -\end{figure} - - -\subsection*{Задания:} -\begin{itemize} -\item \textbf{Конструктор по умолчанию:} Напишите конструктор по умолчанию \texttt{Number()}, который будет создавать число равное нулю. -\item \textbf{Конструктор копирования:} Напишите конструктор копирования \texttt{Number(const Number\& n)}. -\item \textbf{Конструктор из строки:} Напишите конструктор \texttt{Number(const char* str)}, который будет создавать большое число на основе строки. Предполагаем, что на вход конструктору всегда идёт корректная строка. Например, число из примера можно будет создать так: -\begin{lstlisting} -Number a = Number("12345678"); -\end{lstlisting} -\item \textbf{Присваивание:} Напишите оператор присваивания \texttt{Number\& operator=(const Number\& right)}. -\item \textbf{Сложение:} Напишите и протестируйте операторы сложения \texttt{operator+} и оператор присваивания сложения \texttt{operator+=}. Реализовывать оба этих оператора с нуля необязательно. Ведь, если написан один из этих операторов, то очень просто написать другой. -\item \textbf{Числа Фибоначчи:} Числа Фибоначчи задаются следующим образом: -\begin{align*} -F_0 &= 0\\ -F_1 &= 1\\ -F_n &= F_{n-1} + F_{n-2} -\end{align*} -Используйте класс \texttt{Number}, чтобы вычислить $F_{1000}$. Правильный ответ: -\begin{verbatim} -F(1000) = 43466557686937456435688527675040625802564660517371780402481729089536555417949051890 -40387984007925516929592259308032263477520968962323987332247116164299644090653318793829896964992 -8516003704476137795166849228875 -\end{verbatim} - - - - -\item \textbf{Четность:} Напишите метод \texttt{bool isEven() const}, который будет проверять является ли наше число чётным и, если это верно, возвращает \texttt{true}, в ином случае возвращает \texttt{false}. - -\item \textbf{Произведение:} Напишите метод \texttt{Number operator*(const Number\& right) const} - оператор умножения одного числа \texttt{Number} на другое. Протестируйте вашу функцию на различных примерах (умножение большого числа на большое, умножение большого числа на небольшое ($< 100$) или на ноль, умножение двух небольших чисел и т. д.).\\ -\item \textbf{Факториал:} Используйте написанный оператор для вычисления факториала от 1000. \\ -Правильный ответ: -\begin{verbatim} -1000! = 40238726007709377354370243392300398571937486421071463254379991042993851239862902059 -2044208486969404800479988610197196058631666872994808558901323829669944590997424504087073759 -9188236277271887325197795059509952761208749754624970436014182780946464962910563938874378864 -8733711918104582578364784997701247663288983595573543251318532395846307555740911426241747434 -9347553428646576611667797396668820291207379143853719588249808126867838374559731746136085379 -5345242215865932019280908782973084313928444032812315586110369768013573042161687476096758713 -4831202547858932076716913244842623613141250878020800026168315102734182797770478463586817016 -4365024153691398281264810213092761244896359928705114964975419909342221566832572080821333186 -1168115536158365469840467089756029009505376164758477284218896796462449451607653534081989013 -8544248798495995331910172335555660213945039973628075013783761530712776192684903435262520001 -5888535147331611702103968175921510907788019393178114194545257223865541461062892187960223838 -9714760885062768629671466746975629112340824392081601537808898939645182632436716167621791689 -0977991190375403127462228998800519544441428201218736174599264295658174662830295557029902432 -4153181617210465832036786906117260158783520751516284225540265170483304226143974286933061690 -8979684825901254583271682264580665267699586526822728070757813918581788896522081643483448259 -9326604336766017699961283186078838615027946595513115655203609398818061213855860030143569452 -7224206344631797460594682573103790084024432438465657245014402821885252470935190620929023136 -4932734975655139587205596542287497740114133469627154228458623773875382304838656889764619273 -8381490014076731044664025989949022222176590433990188601856652648506179970235619389701786004 -0811889729918311021171229845901641921068884387121855646124960798722908519296819372388642614 -8396573822911231250241866493531439701374285319266498753372189406942814341185201580141233448 -2801505139969429015348307764456909907315243327828826986460278986432113908350621709500259738 -9863554277196742822248757586765752344220207573630569498825087968928162753848863396909959826 -2809561214509948717012445164612603790293091208890869420285106401821543994571568059418727489 -9809425474217358240106367740459574178516082923013535808184009699637252423056085590370062427 -1243416909004153690105933983835777939410970027753472000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 -0000000000000000000000000000 -\end{verbatim} - -\item \textbf{Числа-градины:} Возьмём некоторое число $n$ и будем последовательно применять к нему следующую функцию: -\begin{equation*} -f(n) = - \begin{cases} - n / 2, &\textup{если n - четное}\\ - 3 n + 1, &\textup{если n - нечетное} - \end{cases} -\end{equation*} -В результате получится некоторая последовательность. Например, при $n = 7$ получится: -\begin{verbatim} -7 -> 22 -> 11 -> 34 -> 17 -> 52 -> 26 -> 13 -> 40 -> 20 -> 10 -> 5 -> 16 -> 8 -> 4 -> 2 -> 1 -\end{verbatim} -Последовательность доходит до 1. Вам нужно написать функцию, которая будет по начальному числу находить длину такой последовательности (\texttt{steps}) и максимальное число в этой последовательности(\texttt{max}). Например, для числа $7$, максимальное число в последовательности будет равно $52$, а длина последовательности -- $16$. Напишите программу, которая будет по начальному числу находить длину последовательности и максимальный элемент в ней. - -Тесты для проверки: -\begin{verbatim} -n = 7 steps = 16; max = 52 -n = 256 steps = 8; max = 256 -n = 1117065 steps = 527; max = 2974984576 -n = 4761963248413673697 steps = 2337; max = 9926927712374950744648 - -n = 90560792656972947582439785608972465789628974587264056284658721771 -steps = 1630; -max = 773658021643749360792171137214151494851244403993540980838080564520 -\end{verbatim} -Для решения этой задачи нужно написать оператор сравнения и метод деления на 2 (оператор целочисленного деления можно не писать). -\item \textbf{Раздельная компиляция:} Перенесите объявление класса \texttt{Number} в файл \texttt{number.h}, а определение методов в файл \texttt{number.cpp}. Раздельно скомпилируйте эту программу. -\end{itemize} - -\end{document} \ No newline at end of file diff --git a/seminar02_encapsulation/homework/homework_encapsulation.pdf b/seminar02_encapsulation/homework_encapsulation.pdf similarity index 100% rename from seminar02_encapsulation/homework/homework_encapsulation.pdf rename to seminar02_encapsulation/homework_encapsulation.pdf diff --git a/seminar02_encapsulation/images/number1.png b/seminar02_encapsulation/images/number1.png deleted file mode 100644 index 38e5859..0000000 Binary files a/seminar02_encapsulation/images/number1.png and /dev/null differ diff --git a/seminar02_encapsulation/images/number1.svg b/seminar02_encapsulation/images/number1.svg deleted file mode 100644 index f1e00e8..0000000 --- a/seminar02_encapsulation/images/number1.svg +++ /dev/null @@ -1,263 +0,0 @@ - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - 4 - - 5 - size - capacity - data - - - - - - - 78 - 56 - 43 - 12 - - Number - - diff --git a/seminar02_encapsulation/images/sepcompilation.png b/seminar02_encapsulation/images/sepcompilation.png deleted file mode 100644 index 2586af2..0000000 Binary files a/seminar02_encapsulation/images/sepcompilation.png and /dev/null differ diff --git a/seminar02_encapsulation/images/sepcompilation.svg b/seminar02_encapsulation/images/sepcompilation.svg deleted file mode 100644 index 8963c40..0000000 --- a/seminar02_encapsulation/images/sepcompilation.svg +++ /dev/null @@ -1,338 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - struct Point { float x, y; float norm() const; void normalize(); Point operator+(const Point& r) const;}; - point.h - - #include <cmath>#include "point.h"float Point::norm() const { return sqrt(x*x + y*y);}void Point::normalize() { float pnorm = norm(); x /= pnorm; y /= pnorm;}Point Point::operator+(const Point& r) const{ Point result = {x + r.x, y + r.y}; return result;} - point.cpp - - #include <iostream>#include "point.h"int main() { Point p = {1, 2}; p.normalize(); std::cout << p.x << " " << p.y << std::endl;} - main.cpp - - diff --git a/seminar02_encapsulation/images/string_base.png b/seminar02_encapsulation/images/string_base.png deleted file mode 100644 index f9a0186..0000000 Binary files a/seminar02_encapsulation/images/string_base.png and /dev/null differ diff --git a/seminar02_encapsulation/images/string_base.svg b/seminar02_encapsulation/images/string_base.svg deleted file mode 100644 index dacd891..0000000 --- a/seminar02_encapsulation/images/string_base.svg +++ /dev/null @@ -1,344 +0,0 @@ - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - E - - l - - e - - p - - h - - a - - n - - t - - \0 - 8 - - String a - size - data - - diff --git a/seminar03_initialization/01_letter_case_switch/main.cpp b/seminar03_initialization/01_letter_case_switch/main.cpp new file mode 100644 index 0000000..c866f8b --- /dev/null +++ b/seminar03_initialization/01_letter_case_switch/main.cpp @@ -0,0 +1,22 @@ +#include +#include +#include + +using namespace std; + +string letter_case_switch(const string & str) +{ + string result = str; + if (str.size() == 0) + return result; + result[0] = + isupper(result[0]) ? tolower(result[0]) : toupper(result[0]); + return result; +} + +int main() +{ + string meow; + cin >> meow; + cout << letter_case_switch(meow) << endl; +} diff --git a/seminar03_initialization/01_letter_case_switch/main.cpp~ b/seminar03_initialization/01_letter_case_switch/main.cpp~ new file mode 100644 index 0000000..30f8ff4 --- /dev/null +++ b/seminar03_initialization/01_letter_case_switch/main.cpp~ @@ -0,0 +1,19 @@ +#include +#include +#include + +using namespace std; + +string letter_case_switch(const string& str) { + string result = str; + if (str.size() == 0) + return result; + result[0] = isupper(result[0]) ? tolower(result[0]) : toupper(result[0]); + return result; +} + +int main() { + string meow; + cin >> meow; + cout << letter_case_switch(meow) << endl; +} diff --git a/seminar03_initialization/02_repeat/a.out~ b/seminar03_initialization/02_repeat/a.out~ new file mode 100644 index 0000000..7c4ca02 Binary files /dev/null and b/seminar03_initialization/02_repeat/a.out~ differ diff --git a/seminar03_initialization/02_repeat/main.cpp b/seminar03_initialization/02_repeat/main.cpp new file mode 100644 index 0000000..480bd91 --- /dev/null +++ b/seminar03_initialization/02_repeat/main.cpp @@ -0,0 +1,48 @@ +#include +#include +#include + +using namespace std; + +string repeat1(string_view s) +{ + return string { + s} + +string { + s}; +} + +void repeat2(string & s) +{ + s += s; +} + +void repeat3(string * s) +{ + *s += *s; +} + +string *repeat4(string_view s) +{ + string *result = new string; + *result = string { + s} +string { + s}; + return result; +} + +int main() +{ + string meow; + cin >> meow; + + cout << "test of repeat1:" << endl << repeat1(meow) << endl; + + repeat2(meow); + cout << "test of repeat2:" << endl << meow << endl; + + repeat3(&meow); + cout << "test of repeat3:" << endl << meow << endl; + + cout << "test of repeat4:" << endl << *repeat4(meow) << endl; +} diff --git a/seminar03_initialization/02_repeat/main.cpp~ b/seminar03_initialization/02_repeat/main.cpp~ new file mode 100644 index 0000000..0cbb9c9 --- /dev/null +++ b/seminar03_initialization/02_repeat/main.cpp~ @@ -0,0 +1,38 @@ +#include +#include +#include + +using namespace std; + +string repeat1(string_view s) { + return string{s} + string{s}; +} + +void repeat2(string& s) { + s += s; +} + +void repeat3(string* s) { + *s += *s; +} + +string* repeat4(string_view s) { + string* result = new string; + *result = string{s} + string{s}; + return result; +} + +int main() { + string meow; + cin >> meow; + + cout << "test of repeat1:" << endl << repeat1(meow) << endl; + + repeat2(meow); + cout << "test of repeat2:" << endl << meow << endl; + + repeat3(&meow); + cout << "test of repeat3:" << endl << meow << endl; + + cout << "test of repeat4:" << endl << *repeat4(meow) << endl; +} diff --git a/seminar03_initialization/03_string_multiplication/main.cpp b/seminar03_initialization/03_string_multiplication/main.cpp new file mode 100644 index 0000000..f01e662 --- /dev/null +++ b/seminar03_initialization/03_string_multiplication/main.cpp @@ -0,0 +1,24 @@ +#include +#include + +using namespace std; + +string operator*(const string str, int n) { + string result; + for (int i = 0; i < n; ++i) + result += str; + return result; +} + +string operator*(int n, const string str) { + string result; + for (int i = 0; i < n; ++i) + result += str; + return result; +} + +int main() { + string meow; + cin >> meow; + cout << 3 * meow << endl; +} diff --git a/seminar03_initialization/04_truncate_to_dot/main.cpp b/seminar03_initialization/04_truncate_to_dot/main.cpp new file mode 100644 index 0000000..468312c --- /dev/null +++ b/seminar03_initialization/04_truncate_to_dot/main.cpp @@ -0,0 +1,22 @@ +#include +#include + +using namespace std; + +void truncateToDot(string& s) { + s.resize(s.find('.')); + s.shrink_to_fit(); +} + +int main() { + std::string a = "cat.dog.mouse.elephant.tiger.lion"; + std::string b = "wikipedia.org"; + std::string c = ".com"; + truncateToDot(a); + truncateToDot(b); + truncateToDot(c); + + cout << a << endl + << b << endl + << c << endl; +} diff --git a/seminar03_initialization/05_string_sum/main.cpp b/seminar03_initialization/05_string_sum/main.cpp new file mode 100644 index 0000000..8ffd497 --- /dev/null +++ b/seminar03_initialization/05_string_sum/main.cpp @@ -0,0 +1,35 @@ +#include +#include +#include + +using namespace std; + +int string_sum(const string& str) { + int res = 0; + int x; + int n = str.size(); + int i = 0; + while (i < n) { + switch (str[i]) { + case '[': + case ',' : + sscanf((str.c_str()) + i + 1, "%d", &x); + res += x; + break; + case ']' : + return res; + case ' ': + break; + default: + break; + } + ++i; + } + return -1; +} + +int main() { + string meow; + getline(cin, meow); + cout << string_sum(meow) << endl; +} diff --git a/seminar03_initialization/06_new/main.cpp b/seminar03_initialization/06_new/main.cpp new file mode 100644 index 0000000..dce9e33 --- /dev/null +++ b/seminar03_initialization/06_new/main.cpp @@ -0,0 +1,34 @@ +#include +#include +#include + +using namespace std; + +int main() { + int *x = new int{123}; + cout << *x << endl; + + string *str = new string{"Cats and Dogs"}; + cout << *str << endl; + + int *xs = new int[]{10, 20, 30, 40, 50}; + for (int i = 0; i < 5; ++i) + cout << xs[i] << " "; + cout << endl; + + string *strs = new string[]{"Cat", "Dog", "Mouse"}; + for (int i = 0; i < 3; ++i) + cout << strs[i] << " "; + cout << endl; + + string_view *str_views = new string_view[]{strs[0], strs[1], strs[2]}; + for (int i = 0; i < 3; ++i) + cout << str_views[i] << " "; + cout << endl; + + delete x; + delete str; + delete[] xs; + delete[] strs; + delete[] str_views; +} diff --git a/seminar03_initialization/08_stringview/main.cpp b/seminar03_initialization/08_stringview/main.cpp new file mode 100644 index 0000000..b54382e --- /dev/null +++ b/seminar03_initialization/08_stringview/main.cpp @@ -0,0 +1,16 @@ +#include +#include "miptstring.cpp" +#include "miptstringview.cpp" + +using namespace std; + +int main() { + mipt::String str = "Meow!!"; + cout << str << endl; + mipt::StringView sv = str; + cout << "string view: " << sv << endl; + char a[] = "nyaa!"; + mipt::StringView sv1 = a; + cout << "string view: " << sv1 << endl; + cout << sv1.at(200) << endl; +} diff --git a/seminar02_encapsulation/classroom_tasks/code/2string/12full_string_solution.cpp b/seminar03_initialization/08_stringview/miptstring.cpp similarity index 68% rename from seminar02_encapsulation/classroom_tasks/code/2string/12full_string_solution.cpp rename to seminar03_initialization/08_stringview/miptstring.cpp index 7a2022e..4234748 100644 --- a/seminar02_encapsulation/classroom_tasks/code/2string/12full_string_solution.cpp +++ b/seminar03_initialization/08_stringview/miptstring.cpp @@ -1,233 +1,221 @@ -#include -#include -using std::cout, std::cin, std::endl, std::size_t; - - -class String -{ -private: - - size_t mSize; - size_t mCapacity; - char* mpData; - -public: - - String(const char* str) - { - size_t i = 0; - while (str[i] != '\0') - i++; - mSize = i; - mCapacity = i + 1; - - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; str[i]; i++) - mpData[i] = str[i]; - mpData[mSize] = '\0'; - } - - String() : String("") {} - String(const String& s) : String(s.cStr()) {} - - String(size_t n, char a) - { - mSize = n; - mCapacity = n + 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - mpData[i] = a; - mpData[mSize] = '\0'; - } - - ~String() - { - std::free(mpData); - } - - void reserve(size_t capacity) - { - if (capacity <= mCapacity) - return; - - mCapacity = capacity; - char* newData = (char*)std::malloc(sizeof(char) * mCapacity); - - for (size_t i = 0; i < mSize; ++i) - newData[i] = mpData[i]; - newData[mSize] = '\0'; - - std::free(mpData); - mpData = newData; - } - - - void resize(size_t size) - { - reserve(size + 1); - mSize = size; - mpData[mSize] = '\0'; - } - - - String& operator=(const String& right) - { - if (this == &right) - return *this; - - mSize = right.mSize; - resize(mSize); - - for (size_t i = 0; i <= mSize; ++i) - mpData[i] = right.mpData[i]; - - return *this; - } - - - String operator+(const String& b) - { - String result; - result.resize(mSize + b.mSize); - - for (size_t i = 0; i < mSize; ++i) - result.mpData[i] = mpData[i]; - - for (size_t i = 0; i < b.mSize; ++i) - result.mpData[mSize + i] = b.mpData[i]; - - result.mpData[result.mSize] = '\0'; - - return result; - } - - String& operator+=(const String& right) - { - *this = *this + right; - return *this; - } - - bool operator==(const String& right) const - { - if (mSize != right.mSize) - return false; - - size_t i = 0; - while (i < mSize && mpData[i] == right.mpData[i]) - i++; - - return i == mSize; - } - - bool operator<(const String& right) const - { - size_t i = 0; - while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) - i++; - - return mpData[i] < right.mpData[i]; - } - - bool operator<=(const String& right) const - { - size_t i = 0; - while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) - i++; - - return mpData[i] <= right.mpData[i]; - } - - bool operator!=(const String& right) const - { - return !(*this == right); - } - - bool operator>(const String& right) const - { - return !(*this <= right); - } - - bool operator>=(const String& right) const - { - return !(*this < right); - } - - char& operator[](size_t i) - { - return mpData[i]; - } - - char& at(size_t i) - { - if (i >= mSize) - { - cout << "Error! Index is out of bounds." << endl; - std::exit(1); - } - return mpData[i]; - } - - - void clear() - { - std::free(mpData); - - mSize = 0; - mCapacity = 1; - mpData = (char*)std::malloc(sizeof(char) * mCapacity); - mpData[0] = '\0'; - } - - void addCharacter(char c) - { - if (mSize + 1 == mCapacity) - reserve(2 * mCapacity); - - mpData[mSize] = c; - resize(mSize + 1); - } - - - size_t getSize() const {return mSize;} - size_t getCapacity() const {return mCapacity;} - const char* cStr() const {return mpData;} -}; - - -std::ostream& operator<<(std::ostream& out, const String& s) -{ - out << s.cStr(); - return out; -} - -std::istream& operator>>(std::istream& in, String& s) -{ - s.clear(); - while (true) - { - char x = in.get(); - if (x == ' ' || x == '\n' || x == '\t') - break; - s.addCharacter(x); - } - return in; -} - - -int main() -{ - String all; - String nextWord; - - while (true) - { - cin >> nextWord; - if (nextWord == "quit") - break; - - all += nextWord; - cout << all << endl; - } -} \ No newline at end of file +#pragma once + +#include +#include +#include +#include +using std::cout, std::cin, std::endl, std::size_t; + +namespace mipt{ + +char* errorCheckedMalloc(size_t newCapacity) +{ + char* result = static_cast(std::malloc(newCapacity * sizeof(char))); + if (result == NULL) + { + cout << "Error! Out of memory" << endl; + std::exit(1); + } + return result; +} + + +class String +{ +private: + + size_t mSize {0}; + size_t mCapacity {0}; + char* mpData {nullptr}; + +public: + + String(const char* str) + { + size_t strSize = std::strlen(str); + resize(strSize); + std::memcpy(mpData, str, mSize); + } + + String() : String("") {} + String(const String& s) : String(s.cStr()) {} + + String(size_t n, char a) + { + resize(n); + + for (size_t i = 0; i < mSize; ++i) + mpData[i] = a; + } + + ~String() + { + std::free(mpData); + } + + void reserve(size_t capacity) + { + if (capacity <= mCapacity) + return; + + mCapacity = std::max(2 * mCapacity, capacity); + char* newData = errorCheckedMalloc(mCapacity); + + if (mpData) + std::memcpy(newData, mpData, mSize + 1); + + std::free(mpData); + mpData = newData; + } + + + void resize(size_t size) + { + reserve(size + 1); + mSize = size; + mpData[mSize] = '\0'; + } + + + String& operator=(const String& right) + { + if (this == &right) + return *this; + + mSize = right.mSize; + resize(mSize); + + std::memcpy(mpData, right.mpData, mSize + 1); + + return *this; + } + + + String operator+(const String& b) + { + String result; + result.resize(mSize + b.mSize); + + std::memcpy(result.mpData, mpData, mSize); + std::memcpy(result.mpData + mSize, b.mpData, b.mSize); + result.mpData[result.mSize] = '\0'; + + return result; + } + + String& operator+=(const String& right) + { + *this = *this + right; + return *this; + } + + bool operator==(const String& right) const + { + if (mSize != right.mSize) + return false; + + size_t i = 0; + while (i < mSize && mpData[i] == right.mpData[i]) + i++; + + return i == mSize; + } + + bool operator<(const String& right) const + { + size_t i = 0; + while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) + i++; + + return mpData[i] < right.mpData[i]; + } + + bool operator<=(const String& right) const + { + size_t i = 0; + while (i < mSize && i < right.mSize && mpData[i] == right.mpData[i]) + i++; + + return mpData[i] <= right.mpData[i]; + } + + bool operator!=(const String& right) const + { + return !(*this == right); + } + + bool operator>(const String& right) const + { + return !(*this <= right); + } + + bool operator>=(const String& right) const + { + return !(*this < right); + } + + char& operator[](size_t i) + { + return mpData[i]; + } + + const char& operator[](size_t i) const + { + return mpData[i]; + } + + char& at(size_t i) + { + if (i >= mSize) + { + cout << "Error! Index is out of bounds." << endl; + } + return mpData[i]; + } + + void clear() + { + std::free(mpData); + + mSize = 0; + mCapacity = 1; + mpData = errorCheckedMalloc(mCapacity); + mpData[0] = '\0'; + } + + void addCharacter(char c) + { + if (mSize + 1 == mCapacity) + reserve(2 * mCapacity); + + mpData[mSize] = c; + resize(mSize + 1); + } + + + size_t getSize() const {return mSize;} + size_t getCapacity() const {return mCapacity;} + const char* cStr() const {return mpData;} +}; + + +std::ostream& operator<<(std::ostream& out, const String& s) +{ + out << s.cStr(); + return out; +} + +std::istream& operator>>(std::istream& in, String& s) +{ + s.clear(); + while (true) + { + char x = in.get(); + if (x == ' ' || x == '\n' || x == '\t') + break; + s.addCharacter(x); + } + return in; +} + +} diff --git a/seminar03_initialization/08_stringview/miptstringview.cpp b/seminar03_initialization/08_stringview/miptstringview.cpp new file mode 100644 index 0000000..770aa16 --- /dev/null +++ b/seminar03_initialization/08_stringview/miptstringview.cpp @@ -0,0 +1,59 @@ +#pragma once + +#include +#include +#include +#include +using std::cout, std::cin, std::endl, std::size_t; + +namespace mipt { + +class StringView +{ +private: + const char* mpData; + size_t mSize; + +public: + StringView() {; + mSize = 0; + mpData = nullptr; + } + StringView(const StringView& str) { + mSize = str.mSize; + mpData = str.mpData; + } + StringView(const mipt::String& s) { + mSize = s.getSize(); + mpData = s.cStr(); + } + StringView(const char* s) { + mpData = s; + mSize = strlen(s); + } + const char& at(size_t i) + { + if (i >= mSize) + { + throw std::out_of_range("Error! Index is out of bounds."); + std::exit(1); + } + return mpData[i]; + } + const char& operator[](size_t i) + { + return mpData[i]; + } + size_t size() { + return mSize; + } + +}; +} + +std::ostream& operator<<(std::ostream& out, mipt::StringView sv) { + size_t size = sv.size(); + for (int i = 0; i < size; ++i) + out << sv[i]; + return out; +} diff --git a/seminar03_initialization/homework_initialization.pdf b/seminar03_initialization/homework_initialization.pdf new file mode 100644 index 0000000..8f84c91 Binary files /dev/null and b/seminar03_initialization/homework_initialization.pdf differ