seminar2
This commit is contained in:
		
							parent
							
								
									46d1c64684
								
							
						
					
					
						commit
						ab6732eded
					
				
					 98 changed files with 10319 additions and 0 deletions
				
			
		
							
								
								
									
										34
									
								
								seminar02_encapsulation/classroom_tasks/code/0book/00oop.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								seminar02_encapsulation/classroom_tasks/code/0book/00oop.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | |||
| /*
 | ||||
|     Объектно-ориентированное программирование (ООП) основано на представлении программы в виде совокупности взаимодействующих объектов | ||||
| 
 | ||||
|     Основные принципы ООП: абстракция, инкапсуляция, наследование и полиморфизм | ||||
| 
 | ||||
| 
 | ||||
|     Абстракция: использование только тех характеристик объекта, которые с достаточной точностью представляют его в данной системе. | ||||
| 
 | ||||
|         В каком-то смысле обычные структуры из языка C являются примером абстракции | ||||
| 
 | ||||
|             struct book | ||||
|             { | ||||
|                 char title[100]; | ||||
|                 float price; | ||||
|                 int pages; | ||||
|             }; | ||||
| 
 | ||||
|         Для описание книги в коде мы используем лишь некоторое её характеристики, достаточные для нашей задачи | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     Инкапсуляция: связывание данных некоторого абстрактного объекта и функций для работы с ним | ||||
|         Тесно связано с инкапсуляцией такое понятие как сокрытие | ||||
| 
 | ||||
|     Сокрытие:     разделение данных и функций абстрактного объекта на открытые (видимые извне) и скрытые (видимые только внутри самого объекта) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     Наследование и Полиморфизм будут пройдены позже в курсе | ||||
| */ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| int main(){} | ||||
							
								
								
									
										54
									
								
								seminar02_encapsulation/classroom_tasks/code/0book/01book.c
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								seminar02_encapsulation/classroom_tasks/code/0book/01book.c
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,54 @@ | |||
| /*
 | ||||
|     Хоть язык C и не является объектно-ориентированным, некоторые зачатки подходов ООП в нём тоже есть | ||||
|     Например, структуры языка C являются примером Абстракции | ||||
| 
 | ||||
|     Для работы со структурами мы обычно писали функции так, что каждая из этих функций принимает на вход первым аргументом указатель на наш объект. | ||||
|     Такой подход НЕ является примером Инкапсуляции, так как структура и функции для работы с ней являются независимыми друг от друга. | ||||
|     При желании или по ошибке можно первым аргументом в эти функции передать вообще объект другого типа. | ||||
| 
 | ||||
|      | ||||
| 
 | ||||
|     Эта программа написана на языке C, для компиляции используйте gcc: | ||||
|         gcc 00book.c | ||||
| 
 | ||||
|     Функции в этом примере делают следующее: | ||||
| 
 | ||||
|         make_discount  сделать скидку на книгу, но цена на книгу не может упасть ниже 0. | ||||
|         print_book     напечатать информацию о книге на экран | ||||
| */ | ||||
| 
 | ||||
| #include <stdio.h> | ||||
| 
 | ||||
| 
 | ||||
| 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); | ||||
| } | ||||
|  | @ -0,0 +1,44 @@ | |||
| /*
 | ||||
|     Эта программа написана на языке C++, для компиляции используйте g++: | ||||
|         g++ 01book.cpp | ||||
| 
 | ||||
|     В языке C++ появились ссылки, которые могут немного упростить код из предыдущего файла | ||||
|      | ||||
|     Тем не менее, структура Book и функции для работы с ней всё ещё являются независимыми друг от друга. | ||||
|     То есть тут тоже нет Инкапсуляции. | ||||
| */ | ||||
| 
 | ||||
| #include <iostream> | ||||
| 
 | ||||
| 
 | ||||
| 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); | ||||
| } | ||||
|  | @ -0,0 +1,91 @@ | |||
| /*
 | ||||
|     Инкапсуляция - это объединение данных и функций для работы с ними | ||||
| 
 | ||||
|     Объекты-данные, составляющие наш объект, называются полями | ||||
|     Функции для работы с этими данными называются методами | ||||
|     То есть у структуры 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 <iostream> | ||||
| 
 | ||||
| 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 из константного метода? | ||||
| 
 | ||||
| */ | ||||
|  | @ -0,0 +1,56 @@ | |||
| /*
 | ||||
|     Задачи: Представлена структура 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 <iostream> | ||||
| 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(); | ||||
| } | ||||
| 
 | ||||
|  | @ -0,0 +1,49 @@ | |||
| #include <iostream> | ||||
| 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(); | ||||
| } | ||||
| 
 | ||||
|  | @ -0,0 +1,53 @@ | |||
| /*
 | ||||
|     Ключевое слово this | ||||
| 
 | ||||
|     Используя указатель this внутри структуры, можно узнать адрес объекта. | ||||
|     Например, если метод был вызван таким образом: | ||||
|         a.printThis(); | ||||
|     то внутри метода this будет означать адрес объекта a | ||||
| 
 | ||||
|     С помощью этого указателя можно доступаться до полей класса. | ||||
|     Например,  title  и  this->title  это одно и то же внутри методов структуры. | ||||
| 
 | ||||
|     this можно использовать, если имя аргумента метода совпадает с одним из полей, как, например, в методе setPrice | ||||
|     Внутри метода setPrice поле price перекрывается аргументом price. Но можно всё-равно доступиться до поля price, используя указатель this | ||||
| */ | ||||
| 
 | ||||
| #include <iostream> | ||||
| 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(); | ||||
| } | ||||
| 
 | ||||
|  | @ -0,0 +1,86 @@ | |||
| /*
 | ||||
|     Конструктор | ||||
| 
 | ||||
|     Конструктор - это специальный метод, который вызывается при создании объекта | ||||
| 
 | ||||
|     Конструктор  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 <iostream> | ||||
| #include <cmath> | ||||
| #include <string.h> | ||||
| 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) из библиотеки <cstdlib> | ||||
| 
 | ||||
| 
 | ||||
|         2)  Конструкторы можно перегружать также, как и обычные функции и методы. | ||||
|             Добавьте новый конструктор, который не будет принимать никаких аргументов и будет создавать объект с полями равными | ||||
|             title: "Default"  price: 0   pages: 0 | ||||
|             Вызовите этот конструктор из main | ||||
| 
 | ||||
|             Конструктор, который не принимает аргументов, называется конструктором по умолчанию. | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|         3)  Конструкторы можно перегружать также, как и обычные функции и методы. | ||||
|             Добавьте новый конструктор, который будет принимать объект типа Book (по константной ссылке) | ||||
|             и будет задавать поля текущего объекта, используя поля аргумента | ||||
|             Вызовите этот конструктор из main | ||||
|              | ||||
|             Конструктор, который создаёт объект, используя объект такого-же типа, называется конструктором копирования. | ||||
| */ | ||||
|  | @ -0,0 +1,69 @@ | |||
| #include <iostream> | ||||
| #include <cmath> | ||||
| #include <cstdlib> | ||||
| #include <string.h> | ||||
| 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(); | ||||
| 
 | ||||
| } | ||||
|  | @ -0,0 +1,65 @@ | |||
| /*
 | ||||
|     Сокрытие данных - это разделение данных и функций абстрактного объекта на открытые (видимые извне) и скрытые (видимые только внутри самого объекта) | ||||
|     В языке C++ это реализуется с помощью модификаторов доступа public и private | ||||
| 
 | ||||
|     Все поля и методы объявленные в секции public называются публичными и могут быть доступны извне структуры | ||||
|     Все поля и методы объявленные в секции private называются приватными и не могут быть доступны извне структуры | ||||
|     Приватные поля и методы могут быть доступны только в методах самого структуры (а также в друзьях, но об этом позже) | ||||
| 
 | ||||
| 
 | ||||
|     Назначение сокрытия данных заключается в том, чтобы объекты нельзя было 'поломать' извне | ||||
|     'Поломать' тут означает задать поля объекта бессмысленным образом | ||||
| 
 | ||||
|     Например, в нашем примере мы бы могли поломать объект просто сделав поля price или pages отрицательными | ||||
|         a.pages = -100; | ||||
|     но благодаря тому, что поле pages является приватным, это сделать нельзя. | ||||
| 
 | ||||
| 
 | ||||
|     Учитывая проверку в конструкторе, получается, что поля pages и price в принципе никогда не смогут стать отрицательными. | ||||
|     Таким образом мы уберегли себя от возникновения ошибок при неправильном задании полей структуры. | ||||
| */ | ||||
| 
 | ||||
| #include <iostream> | ||||
| #include <cmath> | ||||
| #include <string.h> | ||||
| #include <cstdlib> | ||||
| 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; | ||||
| } | ||||
|  | @ -0,0 +1,77 @@ | |||
| /*
 | ||||
|     Синтаксис инициализации с помощью коструктора | ||||
| 
 | ||||
|     Язык C++ имеет очень длинную историю и на её протяжении в язык добавлялись новые возможности | ||||
|     В итоге в языке часто можно сделать одно и то же разными методами. | ||||
| 
 | ||||
|     В частности, вызвать конструктор можно 5-ю разными способами. | ||||
|     В этой программе строки для создания книг a, b, c, d, e делают одно и то же, несмотря, что имеют разный синтаксис | ||||
| */ | ||||
| 
 | ||||
| #include <iostream> | ||||
| #include <cmath> | ||||
| #include <string.h> | ||||
| #include <cstdlib> | ||||
| 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-ю разными способами | ||||
| 
 | ||||
| */ | ||||
|  | @ -0,0 +1,62 @@ | |||
| #include <iostream> | ||||
| #include <cmath> | ||||
| #include <string.h> | ||||
| #include <cstdlib> | ||||
| 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(); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -0,0 +1,53 @@ | |||
| /*
 | ||||
|     Классы. Ключевое слово class. | ||||
| 
 | ||||
|     На самом деле классы мы уже прошли. Структуры с методоми из предыдущих файлов это и есть классы. | ||||
|     Для объявления класса может использоваться ключевое слово class. | ||||
| 
 | ||||
|     Разница между этими ключевым словами минимальна | ||||
|         - при использовании struct все поля и методы по умолчанию публичны | ||||
|         - при использовании class  все поля и методы по умолчанию приватны | ||||
|     Но, так как  мы указываем private и public для всех членов, то разницы нет вообще. | ||||
| */ | ||||
| 
 | ||||
| #include <iostream> | ||||
| #include <cmath> | ||||
| #include <string.h> | ||||
| #include <cstdlib> | ||||
| 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(); | ||||
| } | ||||
							
								
								
									
										56
									
								
								seminar02_encapsulation/classroom_tasks/code/0book/10m.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								seminar02_encapsulation/classroom_tasks/code/0book/10m.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,56 @@ | |||
| /*
 | ||||
|     Некоторые замечания по оформлению | ||||
| 
 | ||||
|     1)  Как правило в классе сначала описываются публичные методы, а потом приватные | ||||
|         Так делают потому что если другой программист захочет воспользоваться вашим классом, | ||||
|         то его будет в первую очередь будет интересовать что ваш класс может делать | ||||
|         и уже потом его будет интересовать строение класса. | ||||
| 
 | ||||
| 
 | ||||
|     2)  Приватные поля класса желательно называть так, чтобы их можно было отличить от обычных переменных | ||||
|         Это может сильно упростить понимание при написании/использовании больших програм и библиотек | ||||
|         В данном курсе мы будем называть приватные поля начиная с буквы m | ||||
|         Например,  mTitle  вместо  title | ||||
| */ | ||||
| 
 | ||||
| #include <iostream> | ||||
| #include <cmath> | ||||
| #include <string.h> | ||||
| #include <cstdlib> | ||||
| 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(); | ||||
| } | ||||
		Reference in a new issue