0: Всем снова здравствуйте и
1: В прошлый раз мы остановились на том, что мы сделали некоторый обзор языка. Я выдал 1 домашнее задание сегодня, в начале занятия некоторым из вас снова предстоит испытать щемящее чувство узнавания.
2: Особенно тем, кто был у меня на 1 курсе, потому что если вы помните, то на 1 курсе, в самом начале занятий, я показывал вам некий мультик я вам обещал, что мы к нему ещё вернёмся, когда мы будем говорить про c plus plus. Так вот, я всегда держу свои обещания, и сейчас мы к нему вернёмся.
3: Этот мультик называется генезис. И когда-нибудь я правда запишу его в виде мультика, то есть вот прям чтобы это, чтоб была запись. Итак, у нас есть пустое пространство. Те, кто сейчас пришли, должны быть немножко удивлены, что я показываю
4: На экране у нас есть пустое пространство, и неожиданно в этом пустом пространстве что-то появляется.
5: В нём появляются некие 4 бита.
6: Что это?
7: 4. Кто сказал? 4. Как вас зовут, Василий? Да, эта штука? Вы видите, что если эту штуку истрактовать, как что истрактовать? Как онсайн, число в каком диапазоне?
8: Диапазоне, например, от от нуля до скольки до 15, да, то это явно 4. А можно ли сказать, что вот это означает 1000000?
9: Да, можно. Мы можем этими битами закодировать все что угодно, и пока это просто биты, они просто ничего не значат. Но давайте возьмём и сопоставим этим 4 битам 3 основных штуки. Это их семантическое значение.
10: И мы говорим, что у них семантическое значение 4, это их велью. Диапазон от - 7 до 8. Это их имя. Мы хотим, чтобы они у нас назывались, а, и теперь вот эта область памяти называется переменная, а
11: Мы знаем, как трактовать значение, потому что у нас задан велью диапазон, и мы знаем, что это такое. Мы знаем, что там, в этом велью диапазоне записано велью 4. Достаточно ли этого, чтобы сказать, что мы знаем тип, а
12: Нет, почему?
13: Мы не знаем, можно ли его изменять, а что мы о нём знаем, что такое, что такое. А плюс + 1, например, для него определена операция. Плюс, да, то есть мы не знаем списка его операций. Вот точно такой же б, мы знаем тоже диапазон значений, но мы не знаем опе.
14: И да, действительно, у нас есть 2 основных термина велью тайп это диапазон значений, это число как коробка, сколько мы можем сложить туда-то и туда-то и у нас есть object type и object type, это набор операций.
15: 5 / 2 это либо 2, либо 2 с половиной 0 - 1. Это либо 255, либо - 1. В зависимости от того, как мы трактуем число. Хуже того, некоторые операции могут быть не
16: Определены 127 + 15 для sign чар неопределённая операция, результат может быть любым для sign чар вполне определённая, соответственно, давайте договоримся, что вот эти 4 бита составляют нам целочисленный тип, который называется
17: И 4, и над этим и 4 обычные знаковые операции, и теперь мы можем сказать, что мы знаем тип и 4 мы задали велью тайп, мы задали, мы задали множество операций над этим типом c plus plus. Кстати, это ещё более важно.
18: Потому что в c plus plus над вашими типами вы сможете задавать ваши собственные операции превосходно далее.
19: У нас есть.
20: Вот так, когда тип связан с конкретной ячейкой, и если бы мы говорили о пайтоне или ruby, то это было бы все вот на этом генезис бы закончился, но в отличие от пайтона и ruby, язык c plus plus статически типизированный.
21: И статическая типизация означает, что тип не связан с конкретной ячейкой. Она означает, что тип навсегда связан с именем. То есть вы задаёте имя, вы навсегда связываете его с типом, если вы не связываете имя с типом. Если одно и то же имя может, соответств.
22: Разным типом в разных точках исполнения программы это называется динамически типизированный язык c plus plus статически типизированный язык именно всегда связано с типом, и если бы мы говорили о сишарпе или джаве, то это было бы.
23: Все потому, что всешарп или java это тоже статически типизированные языки, и в сишарпе и джаве объекты живут в вакууме, внутри платоновского пространства виртуальной машины.
24: Но если мы говорим о таких языках, как c c plus plus, наши объекты не живут в вакууме.
25: Где живут наши объекты, что есть у наших объектов, что есть у наших объектов ещё раз.
26: Да, адреса, кто сказал? Адреса Латвии? Да, между нашими объектами я бы только не называл это адресами. Между нашими объектами есть пространственные соотношения. Смотрите, как выглядит вот эта же картинка в языке.
27: Си в языке си эта картинка выглядит вот так.
28: У нас есть рам модель памяти, то есть модель памяти с произвольным доступом. И у нас в этой рам модели памяти. Вот в данном случае на экране изображена вся память, какая у нас есть на этой машине, как, как сказали, целевая архитектура на этой целевой архитектуре у нас 2
29: 22 бита, 22 бита вся память.
30: И вот в этой памяти лежат эти объекты, обратите внимание, сами объекты никак не отделены от объектов, которые лежат рядом с ними, и мы можем говорить о расстоянии, и самое важное расстояние это расстояние от начала памяти.
31: До начала объекта и расстояние от начала памяти до начала объекта, как справедливо отметил Владислав, называется адресом. Вот это расстояние называется адрес, а это расстояние называется адрес б и тип адреса.
32: Это указатель, как вы все должны помнить из языка си тип адреса это указатель. И вот у нас есть и 4 указателя. У меня есть к вам 2 вопроса. 1 вопрос, какой размер на этой целевой архитектуре должен иметь и 4 поинтер.
33: 5 beat спасибо, все понимают почему 5 beat чтобы адресовать все адресное пространство там 22 бита у нас в адресном пространстве если бы он был 4 бита, то он мог бы адресовать только первые 16, поскольку он 5 beat on.
34: Может адресовать? Все замечательно. У меня 2 вопрос к аудитории. Поднимите руку. Кто знает, что такое константа чар подчёркивания бит из файла лимитс точка аш?
35: Кто помнит это из 1 курса? Хорошо, я подскажу чар подчёркивание бит из лимит. Саш, это сколько у нас бит в байте?
36: Вернее не так. Сколько у нас бит в чаре, что специального в типе char.
37: Тип char это минимальная адресуемая ячейка. Вы не можете адресовать в середину чара. Чарами вы адресуете память. В этой памяти мы можем адресовать отдельно каждый бит. Чему
38: Чему, чему равна константа чар бит 1 1 на этой архитектуре у нас 1 бит в байте именно потому, что волшебство типа чар волшебство типа чар волшебство, студ байт из последнего.
39: Стандарта в том, что это, это, это не волшебство в том, что он символ. Он не символ символов, много разных. Волшебство в том, что он задаёт, сколько мы можем адресовать. Отлично. Итак, мы договорились. А союзов Ачар, кстати, чему равен?
40: Нет, он сайзов очар всегда 1. Константа чар бит на ваших ноутбуках скорее всего 8. Ваш чар всегда занимает сайзов от чар всегда 1 по определению. Вот сайзов от int чему равен.
41: А мы не знаем, но обычно типа 4, да, что значит союз? Атент равен 4. Это означает, что он занимает 4 чара. Это значит, что внутри этого Инта вы можете 4 разными способами поставить указатель.
42: Все, соответственно, если бы мы, да, и у нас есть понсту соотношение, мы можем найти некоторые некоторые биты, типа, па, вот мы их нашли, это 3. И вот мы говорим, что вот эти
43: Биты указывают на вот этот объект, а у нас есть между вот давайте поинтер нормальный сделаем, а то меня критиковали на YouTube между вот этими битами и вот этими
44: Битами у нас есть соотношение по инсту. Вот эти биты указывают на вот эти. Хотя вот это, в общем, тоже обычная ячейка памяти. У неё даже есть имя, у неё есть тип, связанный с именем, но тем не менее, почему-то мы смотрим на эти биты и говорим, ага, они указы.
45: Вот на эти биты это все наша интерпретация, все, что у нас на самом деле есть, это линейная модель памяти. Если б мы говорили о языке си, то это было бы все.
46: Прежде чем говорить, что появится в языке си plus plus, давайте немножко поговорим об указателях указатель это расстояние, когда я говорю, что а указывает на что-то, я говорю, что от начала памяти до этого чего-то надо пройти.
47: А и если есть расстояние, может быть, нулевое расстояние в языке си, нулевое расстояние традиционно помечается либо как нол, либо как 0, либо как null, кто знает разницу между 0 и null.
48: Null это макрос, спасибо, мы не Любим макросы, да, кроме того 0 и null отличаются типами, какой тип нуля.
49: Int спасибо конечно тип нуля инт это литерал, типа int какой тип у null.
50: Вот звёздочка нуль это null, это 0, приведённый к вот звёздочке какой тип у null птр.
51: Да, у null птр тип нул птрт, знакомьтесь, это 1 из первых наших типов, у которого есть только 1 значение в языке силас плас, есть несколько типов, например студ нас Роут.
52: Ну, птрт и так далее, у которых есть только 1 значение, которое нам почему-то важно это 1 из них нулптр, это ключевое слово в языке си plus plus, так что на самом деле это не нулптр введён как констант.
53: Типа, ну, птрт это тип, ну, птрт введён как тип, завязанный на ключевое слово нулптр. И когда мы будем говорить о перегрузке функций, мы поймём, почему наш выбор всегда нулптр.
54: Потому что 0 очень легко выигрывает неправильные перегрузки в языке си перегрузок. Нет, беспокоиться там не о чем. В языке си пласс пласс перегрузки есть. Мы должны беспокоиться о перегрузках, поэтому всегда в c plus plus, когда хотите указать, что у вас нуле?
55: Указатель ну птрт наш выбор.
56: Указатели всегда были указателями внутрь массивов, и поэтому указатели поддерживают вот этот смешной синтаксис с квадратными скобочками.
57: Любой указатель если записать а квадратные скобочки б, то это все равно что а сложить с. Б и результат сложения разименовать именно поэтому 2 квадратные скобочки п. Тоже работает я никогда не знал применения этой техники, кроме как произво.
58: Впечатление на студентов, то есть, может быть, есть другие применения, они мне неизвестны, потому что вот это выражение по определению читается вот так вы ставите, а квадратные скобки б вы сложили и все вместе разименовал.
59: Сколько байт будет добавлено к п. Когда мы добавим к нему 2?
60: Зависит от союзов п неправильно зависит от союзов звёздочка п. Спасибо. Так сколько как зависит?
61: Да, 2 умножить на Азов звёздочка п. То есть, когда мы прибавляем к п 2, мы на самом деле прибавляем к п 2 умножить на размер того, на что он указывает. Мы продвигаем его на 2 вот таких штуки, которые он
62: Есть, именно поэтому войд указатель ни с чем нельзя сложить. Мы не знаем, сколько к нему прибавить.
63: Соответственно, если у нас есть вот здесь вот пб, в который, в котором записан адрес пб нулевого, и мы берём и прибавляем к этому пб единицу, то пб.
64: + 1 это пб + 1 на сайзов и 4 сайзов и 4, 4 бита. Соответственно, мы оказываемся вот здесь, и мы указываем на пб 1 вот это пб + 0. Вот это пб + 1. Обратите внимание, сам по себе массив лежит вот здесь.
65: То, что я назвал указатель так же, как massive, это безобразие, это, этого не может быть. Вот этот указатель должен быть назван как-то по другому. Но, допустим, что это правда, указатель, как можно, как можно меня здесь оправдать, в каком случае эта картинка верна?
66: То есть все видят, что пб не может быть статическим массивом, да, если бы он был статическим массивом, у него не было бы физического представления в памяти, он был бы просто вот здесь, чем является пб, чтобы, чтобы мне сейчас не пришлось краснеть.
67: Он не может являться указателем, потому что вот здесь пб 0.
68: Чем является пб. Если бы пб являлся массивом, его не было бы здесь?
69: Пб является указателем на начало динамического массива пб. Это указатель начала динамической памяти, мы сделали малог, и наш малок вернул память вот отсюда, только в этом случае эта картинка верна, в противном случае ума.
70: Массива нет представления. Массив это просто множество его элементов. А вот указатель это настоящая ячейка памяти. Да, задали вопрос, вопрос. А мы можем добавить не сайзов, a3, 4, а именно 1. Добавить 1, а не сайзов, a3, 4. Вы должны
71: Для этого привести пб к char указателю вы кастуете его к char указателю прибавляете 1 у вас прибавляется правда 1 да 1 байт, разумеется, вы можете добавить только только то, что можете адресовать, вы можете переставлять указатели только на валидные ячейки.
72: И вот, если б мы говорили о языке си, это было бы все, но в c plus plus у нас есть уникальная вещь на самом деле в c plus plus у нас есть 2 уникальных возможности 1 уникальная возможность, о которой мы поговорим сейчас она называется эль велью references.
73: И 2 уникальная возможность, о которой мы поговорим чуть позже она называется hr велью references и поговорим об эль велью references эль велью references это ссылки на эль велью сейчас мы поговорим о том, что такое эль велью, и вы пока можете о них думать, как будто это просто двои.
74: Имени у 1 объекта. То есть мы взяли вот этот объект в памяти и назвали его. Мы назвали его. А, а потом мы назвали его же б.
75: Имеем право, наверное в си это невозможно, но в c plus plus это легко, и синтаксис у них это амперсант, и вот этот амперсант ни в коем случае нельзя путать со взятием адреса, который тоже амперсант небо.
76: Sleeping тест все ли в аудитории спят икс это вот этот массив мы берём x ref, мы берём x птр, потом мы делаем x ref + 1 x птр + 1.
77: В итоге, что у нас лежит в этом массиве?
78: 11 и 20 все понимают, почему 11 и 20. Если б мы 2 раза прибавили, у нас бы лежало 12 и 20, да, но что происходит вот на этой строчке? Давайте посмотрим на мои любимые диаграммки, на моих люби.
79: Диаграммка. Я квадратиками обозначаю реальность, а облачками я обозначаю имена, то есть квадратики это реальные сущности облачка, это номинативные сущности. У нас есть вот этот массив. И поскольку это статический массив, у и
80: Нет собственного расположения в памяти в памяти лежит только x 0 x 1.
81: Вот x 0 вот x, 1, y x птр есть собственное расположение в памяти, и он изначально содержит адрес x 0 x ref. Это просто 2 имя для x 0 что происходит, когда мы делаем?
82: X ref плюс равно 1.
83: Просто просто к x 0 прибавляется 1 что происходит, когда мы к x птр прибавляем 1?
84: X птр продвигается.
85: Понимаете, как это работает? Ссылка это просто другое имя. Указатель это адрес. Мы могли бы разыменовать указатель, прибавить 1. Тогда бы он прибавил к объекту.
86: Это очень тонко. Люди, которые начинают работать с эльвель ссылками, часто это путают. Я надеюсь, вы путать не будете дальше, чем ещё ссылки отличаются от указателей, так это тем, что единожды связанную ссылку нельзя перевязать. В этом они похожи на константные указа.
87: То есть, когда сам указатель константный, единожды его связав, его уже нельзя изменить. Заметьте, указатель может быть изменяемым, но на константные данные тогда его можно изменить. Так вот, ссылка это как будто указатель константный, как сам указатель, когда мы
88: Связали икс реф с x. Мы её инициализировали и в этот момент связали.
89: Вот в этот момент, когда мы приравниваем икс реф, равно игрек это тоже самое, что написать икс равно игрек. То есть вот это равно и это равно имеют фантастически разную семантику. Вот это равно связывает ссылку с объектом, даёт объекту новое имя, а вот это
90: Равно присваивает, это разные равно мало того, если мы берём адрес x рёв.
91: X ref. Теперь это просто новое имя для икс. Адрес x ref. Это все равно что адрес x. Поскольку ссылка это платоновский объект, у неё не может быть адреса.
92: Невозможно написать int реф указатель потому что это был бы адрес ссылки, но у ссылки адреса нет ссылка не существует в физическом пространстве, но ссылку на указатель написать очень легко это просто.
93: Другое имя для указателя, потому что указатель в физическом пространстве существует, и у него другое имя быть может, кто мне скажет, можно ли сделать ссылку на ссылку?
94: Нет, конечно ссылку можно сделать только на что-то, что есть в памяти, а ссылки нет в памяти ссылку, но можно сделать сколько угодно ссылок на одно и то же значение правильно, но ссылку на ссылку сделать нельзя.
95: Хорошо, все ли помнят, все ли помнят правила константности для указателей для начала кто мне покажет 2 ошибки на этом слайде?
96: Прямо сейчас на нём компилятор выдаст 2 ошибки.
97: В какой строчке? Хотя бы в 3, в 1, в 3. Почему в 3? Потому что вы лизировали константу? Конечно, я его ни с чем не связал. Не связать ни с чем константный указатель. Все равно что ни с чем не связать ссылку это запрещено.
98: Ругнётся, конечно же. Итак, что такое с 3, с 3 это вспоминаем с прошлого занятия, как мы читаем, читаем вправо, там ничего нет, читаем влево константный указатель на char с 2 это указатель на константный чар. Есть ли какие-нибудь отличия между типами?
99: 2 с. 1 никаких это так называемый вест конст, это так называемый ист конст, приверженность вест консту и east консту, исключительно эстетическая, я бы сказал.
100: Ссылка, ссылки сами по себе всегда неизменяемые. Ссылка может ссылаться на изменяемые или на неизменяемые данные. Вот это, это ссылка на изменяемые данные, вот эта ссылка на неизменяемые
101: И здесь есть 1 терминологический нюанс. Дело в том, что я буду говорить Константная ссылка и не Константная ссылка, что не совсем правильно, потому что, когда я говорю константный указатель, я имею ввиду, что сам указатель неизменяемый. А когда я говорю,
102: Константная ссылка. Я говорю, что данные неизменяемы, но говорить ссылка на константные данные это настолько долго и сложно, что я буду вот немножко, немножко некорректно. Я буду говорить Константная ссылка, но при этом я буду говорить указательно константна.
103: Данные, потому что другие указатели возможны, другие ссылки невозможны. Окей. И у меня здесь есть небольшой примерчик очень. Да, да. Спрашиваю, как узнать, что ты не вышел за пределы памяти, который
104: Никак. А вопрос был. Как узнать, что не вышел за пределы памяти, которая доступна программами? Смотрите, а в норме. Если у вас есть виртуальная память, то вашей программе как бы доступна вся виртуальная память, то есть
105: Если у вас есть виртуальное адресное пространство, то вы можете теоретически получить адрес в любом месте этого виртуального адресного пространства. Будет этот адрес закоммичен на какую-то физическую страницу или не будет, как ваша операционная система решит.
106: Но при этом, если у вас программа работает не с виртуальным, а с физическим адресным пространством, вот, кстати, это хороший вопрос. Давайте на секундочку отмотаем сюда. А как вы думаете, а вот это адресное пространство, какое оно, физичес?
107: Или виртуальная.
108: Виртуальная. Кто-нибудь считает, что она физическая?
109: Так вот, на самом деле оно не то и не другое это память, это память в абстрактной модели выполнения языка си, что делает язык си вслед за ним язык c plus plus таким замечательным они вообще не оперируют такими терминами.
110: Как физическая или виртуальная память язык си язык си пласс пласс оперирует абстрактной экзекьюшн модел внутри абстрактной экзекьюшн модел любой указатель, который вам корректно вернула корректно вызванная функция, например, указа.
111: Указатель, который вам вернула. Вызванная функция, малок указатель, который вы получили, взяв указатель на любую другую переменную. Так вот, любой такой указатель находится внутри абстрактной модели исполнения. И в таком качестве является валидным указателем любой указатель, который вы полу
112: Или невалидным образом, то есть любым другим образом, который вы десериализовать, диска придумали сами, указывает в невалидный диапазон проверить валидный диапазон или в невалидный, указывает указатель, нельзя.
113: В этом его прелесть.
114: Потому что ещё раз любой указатель полученный валидным путём, валиден, а невалидного пути не существует. Отлично. Так вот у меня есть небольшой примерчик, сейчас я вам его покажу, он называется cell рф точка цц.
115: Давайте на него поглядим вот смотрите там все видно да, у меня есть int у меня есть ссылка и у меня есть Константная ссылка и Константная ссылка у меня показывает на
116: Что странное? Константная ссылка у меня показывает на, на результаты работы функции фу.
117: Я вывожу на экран адрес этой штуки адрес x y, адрес ribs.
118: Что у меня будет на экране?
119: Я не беру адрес от ссылки. Спасибо за вопрос. Вопрос был. Разве можно брать адрес от ссылки ещё раз? Ссылка прозрачная штука. Ссылка это просто другое имя чего-то. И когда я беру адрес, я не беру адрес ссылки, я беру.
120: Адрес от того объекта, на который она, ссылка. Проблема в том, что немножко неясен онтологический статус этого объекта, не так ли?
121: Что это за объект, у которого есть вот такое другое имя? Хорошо? Это другое имя. Какое 1?
122: И вот у этого объекта 1 имени нет. Константная ссылка, когда она связывается с эрвель, сейчас мы поговорим о том, что такое эр велью. Она создаёт временный объект. И вот здесь у меня на стеке сколько будет объектов
123: В этой программе.
124: 2 объекта на стеке, 1 x, другой, который создала эта ссылка, они, скорее всего, лягут рядом, и мы, скорее всего, увидим 2 адреса на стеке рядом, правильно? Давайте на них посмотрим.
125: Компилируем и запускаем. Вау, смотрите, мы увидели 2 адреса на стеке, рядом 24 и 20, 20. Мы увидели 2 раза, потому что взять адрес от самого объекта, от константной ссылки на объект нет никакой разницы. Все понимают этот пример, да.
126: Это хорошо, поехали дальше.
127: Использование ссылок представим функцию и функцию нужно считать 2 тяжёлых объекта.
128: Мы можем либо просто передать их туда по значению, почему мы не хотим передавать их туда по значению? Да, потому что мы не хотим возможного копирования немножко цинично. На самом деле мы никуда не уйдём от возможного копирования в 3 варианте.
129: Ну, предположим, что уйдём, а здесь указатели и мы, мы хотим, мы не, мы не хотим внутри функции постоянно разыменовывать указатели, а здесь ссылки. И вот эта сигнатура испол.
130: Пользует указатели неявно, и вы скажете, что
131: Это противоречит всему, что я только что говорил. Я говорил, что ссылка это всего лишь 2 имя объекта, но внутри этой функции, как компилятору, передать внутрь этой функции. 2.
132: Имя чего-то, что есть вне этой функции.
133: Единственный Разумный способ сделать это на уровне ассемблера это что сделать?
134: Передать туда адрес. Конечно, ссылка это такой же механизм косвенности, как указатель внутри 1 стекового фрейма. Ссылка это всего лишь другое имя внутри другого фрейма. Например, когда вы вызываете функцию, гоните ссылку туда.
135: Это тоже другое имя. Просто у компилятора нет другого выбора, кроме как неявно, невидимо для вас использовать здесь указатель. У меня есть замечательный пример. Ещё 1. Сейчас они закончатся, и мы пойдём дальше по sly.
136: Который называется птрв цц. И вот смотрите, я сделал функцию фу, в которую передал указатель, и глобальной переменной разименовал этот указатель. Я сделал функцию бар, в которую передал ссылку глобальной переменной, присвоил этот самый икс.
137: Все догадываются, сильно ли будет различаться ассемблер. Вообще не будет. Конечно, конечно, вообще не будет. Давайте минус о 1 минус с минус же 0, например. И давайте посмотрим на этот птр.
138: И мы видим, что давайте только включим интелловский синтаксис.
139: И мы видим, что у нас фу, что что делает фу, оно двигает в я x дворд птр рди, то есть оно считывает что-то по адресу рди, то есть по адресу 1 аргумента, после чего кладёт в же райпи я x. Почему же адресовано относительно райпи?
140: Потому что адрес 6 четырехбитный, все помнят этот трюк с ip. Адресация относительно райпи нужна, чтобы ходить недалеко же. Глобальная переменная, она может быть где угодно, но мы не хотим работать с 6 4 битным адресом. Мы хотим вместо этого работать с близкими адресами, и поэтому
141: Мы говорим, что же, скорее всего, недалеко от того места, где мы сейчас и адресуемся, не от начала памяти, от того места, где мы сейчас аналогично. Функция bar. Смотрите, она делает все тоже самое, то есть компилятор, когда ему нужно как-то передать информа.
142: О 2 имени делает Ровно то, что может сделать, передаёт указатель кто догадается, если мы сохраняем ссылку в структуру, ссылку как поле структуры или как поле класса, что на самом
143: Недели будет лежать в этой структуре.
144: Указатель, конечно, то есть ссылки очень похожи на указатели, на указатели, которые чем-то отличаются от обычных указателей, чем ссылки отличаются от обычных указателей.
145: Хранятся, хранятся. Вы же видели, здесь они передаются на рд. Идёт настоящий указатель, как
146: Да, на них нельзя. Нельзя. Они постоянно 1. Да, спасибо. Во первых, их нельзя подвинуть. Да, они константные в некотором смысле. Но, во вторых, они не могут быть на птр.
147: То есть для того, чтобы ссылка была null птр, как указатель, она должна указывать на некий мифический объект, null жел велью, которого в стандарте просто нет, поэтому здесь мы можем быть уверены, что этот объект есть, а здесь мы не можем быть уверены здесь.
148: К нам может прийти новый птр. Мало того, ссылка всегда валидна, указатель может быть невалидным, там вопрос, где ещё применяются ссылки за пределами аргумент.
149: Спасибо, хороший вопрос. Вот сейчас я на него отвечу. Вот он и slide, например, вам нужно изменить что-то в кишках объекта опсам 5 гас интернал, вы берете туда?
150: Ссылку вы даёте вот этому сложно названному объекту. Простое имя. Если вы возьмёте указатель, то над указателем есть адресная арифметика, и вы можете чис.
151: Гипотетически сделать вот так и вообще все испортить. Понятно. Вы хотели здесь звёздочку поставить, но забыли. Над ссылками невозможна адресная арифметика, когда вам нужно просто доступаться к чему-то по косвенности и не нужна адресная арифметика. Пожа.
152: Пожалуйста, всегда используйте ссылки, а не указатели, потому что с указателем, вот вы берете указатель на объект на стеке, мне кажется, нет ничего страшнее, чем взять указатель на объект на стеке, потому что вы берете указатель на объект на стеке. А что будет, если вы прибавите к нему 5 а
153: Добавление 5 это законная операция интерфейсом показателями. Понимаете? Ссылка лишает вас незаконных операций над из интерфейса. Многие считают это опять.
154: Священная война, что ссылка это плохой синтаксис для out аргумента если мы делаем аут аргумент по ссылке и вызываем фу от икс, то неочевидно, что x тут изменится, а если по указателю, то очевидно, что x будет изменён что вы думаете, что вы?
155: Думаете о людях, которые так считают, кто согласен? Кстати, вау, остальные не согласны?
156: Нет, смотрите, они люди, которые вот давайте воспроизведём аргументацию. Человек говорит, смотрите, это небезопасно. Вы передали, он у вас, он у вас тихо изменился, у вас неясно синтаксиса вызова. Что это auto параметр, что вы ему ответите?
157: Он не умеет кадр смотреть. Нет, нет, нет, вы не должны так отвечать, вы должны, вы должны как-то ответить, чтобы сразу, чтобы поддержать диалог конструктивным, чтобы сразу не перевести его в оскорбление, то есть интернет многих.
158: Испортил. Давайте ответим что-нибудь конструктивное.
159: Ответить конструктивное можно так, а здесь, здесь же тоже не очевидно, здесь не очевидно, что это не массив.
160: То есть в 1 случае неочевидно и в другом случае неочевидно я лично считаю, что out я лично считаю, что out аргументы сами по себе очень плохи, если вы хотите что-то вернуть, возвращайте по значению или структуру аут аргумент.
161: Плохих сложно исправить указатели их не исправляют, ссылки их не исправляют, и дополнительный аргумент я уже приводил, очевидно, что икс содержит инт. Не очевидно, что x не nonpoint, это очень важно хорошо, итак, ссылки намного луч.
162: И теперь мы договорились, что вы будете пользоваться ссылками, а не указателями, где это возможно проблема в том, что это немножко не сходится с тем, что я говорил на прошлой лекции, я говорил, что this это указатель, но разве для this нужна адресная арифметика?
163: Разве зис может быть ptr вот возьмите все те аргументы, которые я сейчас перечислил, и примените их к this по всему, что я только что сказал this, должен быть ссылкой, правда ведь?
164: Нет ни 1, ни 1 разумной причины, по которой this это указатель или или есть, или кто-нибудь назовёт, это константный указатель, поэтому тоже самое, что this не является константным указателем.
165: В неконстантных методах.
166: Да, this это не в том-то и проблема. Проблема this как раз в том, что вы можете к нему присвоить. Иногда вы к нему будете присваивать, к сожалению вот и даже в этом курсе. Так вот, правильный ответ.
167: Да, действительно, ни 1 разумного аргумента проблема в том, что язык проектировался исторически в таком порядке бернис роструп придумал зис раньше, чем он придумал ссылки, и поэтому this это указатель, а дальше все засохло.
168: Да спрашиваю ну то есть спрашивают что out аргументы помогает если хочется вернуть пару вещей если хочется вернуть пару вещей верните структуру с парой вещей, зачем вам для этого auto аргументы компилятор сам переделает вашу структуру в
169: Аргумент невидимо для вас, и теперь мы внезапно внезапно переключимся от ссылок на нечто, что, кажется, не имеет отношения к ссылкам сейчас вы увидите, что имеет.
170: Я надеюсь, что мы ровненько уложимся по времени, и мы успеем дойти до того момента, когда у нас эти 2 линии сойдутся, и мы поговорим немножко о вычислительной геометрии.
171: Простая задача. Контестная задача. Мы все решали контест на 1 курсе. Да, мы Любим контест.
172: Со стандартного ввода приходят 2 набора точек. Вот смотрите, что такое 00:00. Это вот это 0 0 это x. Дальше 0 это игрек. Дальше что такое 0 1 0 1. Это вот это 1 0 это вот это, это красный треугольник. Дальше 0 0. Это вот это 1 1 это
173: Вот это 1 0, это вот это, это синий треугольник. Все понимают. Формат ввода. Мы должны, получив, мы должны, получив эти числа этих чисел, немного, как вы видите, их всего 12. Мы должны сделать функцию, которая выводит площадь пересе.
174: 0 точка 25.
175: Сложная ли эта задача или простая?
176: Давайте я у кого-нибудь спрошу.
177: А где Андрей?
178: Андрей, а где? А вот, Андрей, вы довольно неплохо программируете. За сколько бы вы решили такую задачу?
179: Хороший ответ, у кого есть эстимейшен по этой задаче? Вот вам дают вам босс приносит такую задачу и говорит, скажи мне срок. Скажите, скажите мне срок сколько, сколько нужно на эту задачу в прошлом потоке?
180: Кстати, был молодой человек, который мне сказал 3 часа, ну и потом сдавал мне её до зимы. Да ну, не совсем её похожую. Андрей, а почему вы засомневались?
181: Хорошо, а если, а если я вам расскажу алгоритм, как это делать, тогда сколько?
182: Очень простой, линейный. Нет, даже если я расскажу вам алгоритм, сложно, да? Ну, кажется, тут не сильно сложно, достаточно найти точку пересечения. Вот.
183: Ага, тут будет довольно много точек пересечения. Давайте, да, но идея правильная. Как вас зовут? Андрей, Андрей? Андрей высказал правильную идею. Правильная.
184: Идея заключается в чем? Давайте посмотрим на то, как может выглядеть решение. Да, давайте руками нарисуем пересечение нескольких треугольников и посмотрим, а что такое вообще пересечение 2 треугольников.
185: Примерно вот так. Пересечение 2 треугольников может быть шестиугольником, оно может быть пятиугольником, оно может быть четырехугольником, оно, разумеется, может быть трехугольником, но если оно треугольник, то оно может быть довольно мерзким треугольником, потому что точка пересечения может быть тольк.
186: 2, а пересечение все равно треугольник. Мало того, оно может быть треугольником, лежащим вот так. Или оно может быть треугольником, целиком лежащим в этом треугольнике, или они могут пересекаться по целому множеству точек и так далее.
187: Не выглядит мерзко.
188: Такое чувство, кстати, что алгоритмов решения может быть больше, чем 1.
189: С чего бы вы начали написание такой программы?
190: Вам говорят, хорошо, мы услышали ваши аргументы. Задача сложная. Мы даём вам месяц. Как вы начнёте тратить этот месяц? С чего вы начнёте?
191: Ага, со структур данных, говорит Василий. Да, Василий, со структур данных, говорит Василий. Все понимают, что это правильный ответ, что правильно начать.
192: Со структур данных, какая базовая структура данных нам здесь нужна. Конечно, нам нужна структура данных для точки спасибо. Разумеется. И эта задача раньше была 1 уровнем 2 домашнего задания.
193: С тех пор, как её решили, я подвинул 2 домашнее задание на 1 уровень. Теперь она начинается с того, что раньше было 2 уровнем, a1 уровень я вынес на слайд. И эту задачу решил 1 из лучших моих студентов Дима Бушев. Он сейчас работает у меня, и он
194: Решил её я его решение немножко модифицировал, чтобы немножко его упростить. Он решил её сложновато там с генератором Тестов, со всем прочим. Вот я немножко упростил его решение, прям вынес его опять-таки в код, да.
195: Спрашиваю сумма разницы чего ещё раз? Я тоже не понял вопрос. Значит, итак, и то, с чего начал Дима, он начал с того, что он написал именно что
196: Структуры данных. И 1, что он написал, это структура данных для двумерной точки, для отрезка, для треугольника, для полигона и так далее. Это базовая вещь, с которой мы начинаем написание любой программы. Мы берём все существит
197: В нашей предметной области и назначаем этим существительным типы.
198: И вот смотрите, вот точка, вот точка, вот линия, вот, соответственно, дальше полигон и так далее. То есть мы берём
199: Говорим, у нас есть типы, и дальше мы выделяем над ними операции, и опять-таки для любого разумного алгоритма нам понадобятся какие-то примитивные операции пересечь отрезки, посчитать взаимное расположение, точки отрезка, построить
200: Polygon как выпуклую оболочку множества точек да, и вот эти вещи они будут методами у наших классов у нас есть типы, у типов есть методы в качестве методов и на этапе проектирования.
201: Как раз алгоритм менее важен. Хорошо спроектированная программа называется хорошо спроектированной, потому что она переживает смену алгоритма. Вы меняете алгоритм и ничего больше не меняете. У вас все продолжает работать.
202: Хорошо спроектированную программу можно быстро поменять алгоритм, поэтому сначала мы проектируем типы и потом над этими типами мы делаем алгоритм структура для точки, давайте обсудим структуру для точки Дима спроектировал точку. Вот так точка.
203: Состоит из 2 флот полей, которые при конструировании точки сразу устанавливаются в нам. То есть если вы эту точку сконструируете без аргументов, у неё поля не будут не определены, они будут это если бы вы написали конструктор и сразу в этом конструкторе
204: По умолчанию поставили их в на это тоже самое только проще вы можете писать равно прямо в теле структур.
205: Почему он так сделал? И мало того, дальше он написал метод из велит, который проверяет, и точка валидна. Только если ни 1 из 2 координат не none и не инф. Зачем нам, зачем нам вот эта штука, чтобы задание конкретной точки
206: Не работает, ну, до конструирования точки. То есть, когда мы точно задали икс игрек. Так, так, но это вынуждает вас постоянно проверять, валидна ли она, зачем нам вообще возможность иметь
207: Инвалидные точки.
208: Чтобы они были полями, чтобы они были полями класса. По моему, это ещё хуже. 1 единственная невалидная точка делает невалидным целый полигон вообще иметь в программе невалидные объекты. Это сомнительная идея, она в данном случае интересна.
209: С чем работать? С вводом работать. Ну вот это 2 треугольника, где там могут быть невалидные точки? Или вы, или вы хотите работать для пересечения 2 невалидных треугольников точки пересечения.
210: Спасибо. Конечно, конечно, Катя абсолютно права. Смотрите, ну, поделили мы что-нибудь на что-нибудь в конструкторе, и у нас точка пересечения, её просто нет, и она по нашему геометрическому алгоритму, там деление на 0 вылетело куда-нибудь в инф и
211: Она все ещё несмотря на то, что она невалидная, но с точки зрения системы нашей программы это возможная точка. То есть мы можем анализировать точки на извелит и не беспокоиться о том, что наша флатовая арифметика иногда будет улетать.
212: В инфы и наны, и это будет всего лишь означать, что мы где-то получили некорректное деление и метод иквел, он должен проверять относительно какого-то fleur толеранс, но он проверяет относительно какого-то fleur толер, дальше Дима сделал линию линия.
213: Сделано вот в таком виде а x плюс б игрек плюс ц а.
214: Но при этом линия конструируется из 2 точек из п 1 и п 2 поднимите руку кто сдал линал на отл 10, как вас зовут, как бы вы написали конструктор такой линии из 2.
215: Точек, вы бы написали в конструкторе решение системы уравнений? Не, не, нет. Как бы вы конструктор написал.
216: Человек, который хорошо знает линейную алгебру, должен писать такой конструктор сразу, не задумываясь.
217: Дальше.
218: Что вычесть? Господи, ребят, вы гивы вообще сдали? Смотрите.
219: Что ещё раз определитель расписать?
220: Потрясающе. Вот Дима сделал немножко по другому. Дима сделал вот так. Несмотря на то, что это решение выглядит угрожающе, вы можете заметить, что здесь дешёвые операции. Арктангенс это Дешёвая флотовые операция, это
221: 1 операция синус, Дешёвая операция. Здесь немножко подороже, потому что надо перемножать, но, в общем, тоже довольно дёшево.
222: Однако вы видите этот код, и вы видите, что он, ну, нетривиальный, может быть, вы написали бы иначе, вы, может, написали бы через решение системы уравнений или через определитель. А как вы будете тестировать, у вас ещё алгоритма нет, но вы
223: Уже что-то написали и вы уже что-то хотите тестировать, как вы будете это тестировать?
224: Здесь где-то сидит человек, который знает ответ. Как вас зовут? Георгий? Георгий? Георгий прислал мне домашнее задание, в котором содержался ответ на этот вопрос как вы будете тестировать этот конструктор?
225: Да, конечно, Георгий молодец кстати, единственный из всех, кто прислал мне домашнее задание, поглядел немножко вперёд и написал юнит тесты это правильно, у нас. В прошлый раз мы говорили о end to end тестах, мы говорили о том, что мы пишем тест.
226: Со входными данными прогоняем его через всю программу, получаем выходные данные, но e2e тестирование иногда грубовато, и в тонких случаях нам могут понадобиться модульные тесты, тест, который берет и вот испытывает только конкрет.
227: На конструктор, например, вот такой тест вы делаете 2 точки, вы делаете линию через эти 2 точки. И поскольку эти точки 0 0 и 1 1, вы уверены, что a равно b, и вы уверены, что ц.
228: Нулю, да.
229: И вы это тестируете, вы тестируете это макросом чек. И здесь я хочу открыть вам 1 небольшой секрет. Вовсе не обязательно писать свою систему юнит Тестов.
230: Ну, серьёзно, нет, правда, вы не поверите. Очень многие люди пишут этот макрос чек самостоятельно и дальше начинают наворачивать. Вот этого не нужно делать. Возьмите google. Тест, возьмите бус тест.
231: Возьмите хедер онли кач, возьмите любую разумную систему юнит Тестов и наверните её на свою программу. Вы можете в качестве эксперимента попробовать попробовать потестировать, попробовать вот эти системы юни Тестов на, выложи
232: Code, прикрутить какие-нибудь юнит тесты, либо вы можете попробовать их на собственных домашних заданиях, что даже будет ещё лучше.
233: И теперь идея общего алгоритма, идея общего алгоритма проста, как правда предположим, что все вершины, составляющие полигон, отсортированы по кругу вокруг его центра смотрите, у нас есть нулевая вершина и 1 вершина.
234: А значит, вот это 2, теперь нулевая сторона сконструирована 0 и 1 вершиной. 1 сторона сконструирована 1, 2 вершиной. 2 сторона сконструирована 2 0 вершиной. Понимаете идею, да?
235: В чем алгоритм? Мы пересекаем полигон каждой стороной другого полигона мы пересекаем полигон вот этой стороной и выбираем то полупространство, в которой лежит n плюс 2 точка.
236: Это очень простой алгоритм. Мы пересекли и выбрали вот это полупространство. Дальше мы пересекли вот этой стороной и выбрали вот это полупространство. Вот эта сторона не пересекает, значит, оставшийся оставшееся пересечение, вот это
237: Это и есть корректное пересечение треугольников.
238: Очень простой алгоритм, у нас точки полигона отсортированы по кругу, точки 2 тоже отсортированы по кругу, мы пересекаем, мы пересекаем для энной стороны, мы оставляем полупространство в n плюс 2 точке.
239: По модулю. Если мы переполняемся, мы крапаем, я по модулю. Идея алгоритма понятна. Да, алгоритм красивый, изящный.
240: И dima его реализовал в своём решении вот так сейчас покажу.
241: Вот он get Поли intersection очень хорошая функция, очень красивая, занимает буквально 10 строчек эназа это another cat Поли балайн, сай вертиси и + 2 по моду.
242: Секс.
243: И это превосходно.
244: Но здесь есть 1 проблема.
245: Проблема здесь заключается в том, что ничто не мешает пользователю вот этого метода.
246: Get Поли intersection. Вызвать его у полигона, который не удовлетворяет критерию отсортированности точек по кругу. Что будет, если мы такой алгоритм применим, а точки не были правильно отсортированы.
247: По кругу, да, мы вообще черти что будем выбирать. Вот. Поэтому, поэтому что делать? Можно ввести принудительную сортировку вершин по кругу, то есть перед тем, как
248: Пересекать полигоны. Мы до этого сначала говорим сначала мы сортируем вершины по кругу, только потом пересекаем, кто за этот вариант.
249: Ну, разумеется, отсортировать вершины по кругу это более сложно, чем пересечь полигон, не так ли? Это н логарифм, н против отн. Да, поэтому мы так не хотим делать и для того, чтобы понять, а что же мы хотим делать?
250: Сейчас мы изобретём объектно ориентированное программирование, как вы понимаете, чтобы понять, а что же мы хотим делать, да работает ли это?
251: Если полигон не выпуклый, то будут проблемы. Если полигоны выпуклые, то все хорошо. Если он не выпуклый, конечно, будут проблемы. Конечно, конечно, нет. Смотрите, у нас может прийти любой полигон. Это же, это же обобщённый код, он просто для любого полигона, для любого вектора точек. Но, да.
252: У нас есть, смотрите, у нас есть 2 инварианта, которые мы бы хотели, чтобы всегда выполнялись. 1 инвариант, точки отсортированы по кругу. 2 вариант совершенно точно. Полигон выпуклый. Как мы гарантируем, что это выполняется.
253: И мы гарантируем, что это выполняется по построению.
254: И сейчас я вам покажу, как мы можем это сделать. Вернёмся к вернёмся к спискам, на секундочку вернёмся к спискам. Вот представьте, что вы пишите свой собственный список на си, давайте напишем свой собственный список на си плюс плюс вот
255: Вот так вот мы его написали. Шаблон, структура, в ней структура ноды и 2 ноды топ и бэк. Можем ли мы для него написать метод ленс?
256: Да, можем от топ перебираем, перебираем, перебираем, пока не встретили бэк, да.
257: Будет ли это хорошей идеей? Почему?
258: Нет, это, ну типа, а как ещё лучше то? Это же лист. Нет, это, это нормально, это латте. Но вы уверены, что в этом списке нет петли, что кто-нибудь взял и не переставил бэк в петлю? Вот вы написали вот такой метод ленс, а потом
259: Кто-то вызвал его на список с петлёй внутри он зациклился навсегда это действительно немножко долго.
260: Можем ли мы проверить, что в списке нет петли? Поднимите руки. Кто, кто помнит, как мы можем проверить, что в списке нет петли? Влад черепаха да заяц черепаха, алгоритм флойда. Конечно, конечно, 1 курс встретились. Значит, петля есть. Окей.
261: Алгоритм флойда, мы можем запустить алгоритм флойда, можем определить длину, а теперь представим, что мы захотели написать метод reverse.
262: И метод реверс у списка, что в начале опять надо вызвать алгоритм флойда это означает, что мы удваиваем сложность, что мы хотим сделать на языке си, что мы хотим сделать.
263: Да, на языке си мы хотим загнать структуру списка в отдельный модуль.
264: Да, и сделать так, чтобы все методы, которыми пользователь оперирует, знали, что они точно оперируют над списком, который не содержит петли по построению. И вот
265: Это вот знание, что что-то точно не содержит чего-то по построению, это интуитивно, какое-то довольно важное знание.
266: И давайте выучим несколько слов. Смотрите, у нас есть предусловие. И предусловием эффективного метода реверсу списка является то, что этот список это корректный двусвязный список начинается нулём, заканчивается нулём, не сломан нигде внутри.
267: И у нас есть утверждение, которое верно все время жизни объекта какого-то типа. Это утверждение называется инвариантом. Все время жизни списка у нас должна сохраняться корректность, отсутствие петель.
268: Терминированность как инварианты класса и в языке си. Мы знаем, что мы для этого используем что-то вроде инкапсуляции в языке си. Мы говорим, у нас есть непрозрачный объект, лист, который только там
269: В реализации. Мы знаем, что это такое. В хедере. Мы не знаем, что это такое, и у нас все методы возвращают только указатель на него или берут только указатель на него. И в итоге все инварианты сохраняются. Никто не может сделать нам петлю, пока мы не pre.
270: Оставим метод, сделай петлю. Это работает в языке си. Что не так с этим? Что не так с этим подходом в языке? Ну что не так с этим подходом? Почему мы не хотим так делать? Класс класс.
271: Во первых, да, манглии овать руками, каждый раз передавать указатель, но фундаментально фундаментальная проблема. Здесь то, что мы не можем создать такой объект на стеке, мы заплатили очень дорого. Теперь мы не можем созда.
272: Объект на стеке. Теперь мы не можем эффективно ланить функции туда. Вот это большая проблема.
273: И в c plus plus есть механизм, который называется инкапсуляция, и это очень важно понимать, что инкапсуляция в c plus plus это не просто так. Инкапсуляция я видел людей, которые механически засовывают в пра.
274: Вот часть всегда и все. Нет, мы должны понимать, зачем нам инкапсуляция. Инкапсуляция сделана для полезной цели. Инкапсуляция помогает сохранять инварианты класса, если
275: У вас есть инвариант класса, который вы хотите охранять. Тогда вам нужна инкапсуляция. В случае списка вы засовываете в приватную часть указатель топ указатель бэк и структ нота. Ну, с её, соответственно, определением и теперь
276: Теперь вы уверены, что ваш список никто не запутает? У вашего списка есть вариант, поскольку он в приватной части. С вот этой приватной частью класса могут работать только методы класса.
277: Ну, скажем так, почти только методы класса. Там есть ещё дружба, но дружба это магия. Мы пока не будем о дружбе в хорошо спроектированной программе. У вас нет друзей?
278: Дальше в структуре, вот видите, структура в структуре, по умолчанию все поля открытые, поэтому, если вы хотите что-то закрыть, вы должны писать private явно.
279: Поэтому у нас есть другое ключевое слово, ключевое слово класс и класс имеет от структуры 2 отличия.
280: И 1 отличие в том, да, о 2 отличии мы поговорим, когда мы поговорим о наследовании. 1 отличие класса абстракт в том, что у класса по умолчанию прайвет, если вы хотите что-то открыть, вы явно пишите паблик. Вот классы структура
281: Отличается только этим и ещё 1 тонкой штукой в расследовании и все, больше ничем.
282: Спрашивают, можем ли мы с помощью получить доступ к отличный вопрос. Спасибо. Спасибо за этот вопрос. Странно, что его не задал никто, потому что никто из вас, потому что ему посвящён мой следующий слайд. Дело в том, что в
283: В этот момент кто-то из вас должен был вспомнить начало лекции и закричать он должен был закричать господин лектор, сейчас вы противоречите тому, что сказали в начале лекции. Помните мы?
284: В начале лекции, в начале лекции, я сказал, что у нас есть линейная модель памяти, в которой объекты друг от друга никак не отделены, в которой мы берём начало любого объекта и шагаем по нему указа.
285: По всем позициям, где в этом объекте могут быть указатели. И тут я вдруг говорю о каких-то скрытых Полях.
286: А что мешает, что вам мешает привести указатель на ваш объект к char указателю, что вам мешает привести указатель на ваш объект чар указателю и поправить там все что все что угодно инкапсулировать?
287: Кому что мешает, какой правильный ответ, кто мне скажет правильный ответ? Что вам мешает?
288: Ничего не мешает неправильно. Компилятор, компилятор не мешает. Это неправильный ответ, Василий.
289: Да, вам мешает совесть, правильный ответ. Совесть вам мешает совесть? Смотрите, модификаторы private и public не имеют никакого отношения к сокрытию данных модифика.
290: Private public имеют отношение к доступу к именам.
291: Вы не можете использовать в программе имя, которое было объявлено прайвет и public private public это не модификаторы на данные, это модификаторы на имена данных. Если вы используете такое имя, компилятор вас остановит.
292: Ну, если ваш класс стендарт Лаут или 3 велик пейбл, и мы поговорим об обоих концепциях отдельно, мы поговорим о 3 велика пейбл. Когда мы поговорим о конструкторах копирования, мы поговорим о стендарт Лаут уже довольно скоро, то в этом случае
293: Да, если ваш класс не стандарт Лаут или нет ривали копиил, то приводить его к char указателю вы тоже можете, но тогда это уб и до свидания, а вот если он 1 1 или другой, то мы конечно можем привести его к char указател.
294: Мы, мало того, мы можем копировать объекты таких классов с помощью мем сипиай, никаких проблем, но мы не хотим этого делать, и мы не хотим этого делать, потому что мы знаем, что op существует форе ризм, потому что
295: Мы знаем, что у объектов есть инварианты и что объект, у которого нарушены инварианты, это объект в неконсистентном состоянии, и мы не хотели бы иметь в нашей программе объектов в неконсистентном состоянии.
296: Несмотря на то, что те из вас, кто сделали привор к этому курсу и посмотрели мою лекцию по стандартам, могут сейчас поднять руку и сказать а что, а что, а что такое неконсистентное состояние, мы не знаем такого в стандарте.
297: Такого нет в стандарте есть undefined, он специфай там нет, inconsistent его там правда нет, неконсистентное состояние это такой мета термин это так просто называется объект, у которого нарушены
298: Список, в котором не должно быть петли, но в котором есть петля, это неконсистентный список. Итератор, который указывал на какую-то память этой памяти, больше не существует. Это неконсистентный или невалидный итератор, полигон, в котором вершины отсортированы не по
299: Кругу, а все его методы рассчитывают, что они отсортированы по кругу. Это неконсистентный полигон. Ни 1 программист в своём уме, несмотря на всю свободу совести, которую гарантирует нам язык сипла плас не
300: Приведёт хороший объект в неконсистентное состояние. Я надеюсь, вы так тоже не будете делать, потому что да, это выстрел, это выстрел себе в ногу, это выстрел куда угодно. И давайте теперь посмотрим, причём тут
301: Ссылки, ссылки тоже сохраняют инварианты.
302: Ссылка это разновидность инкапсуляции указателя.
303: Когда мы передаём куда-то указатель, у нас в указателе есть 1 метод открытого интерфейса, о котором я вам пока не говорил, а вы не вспомнили, но он есть, это метод, дилет.
304: Когда мне передают указатель, я имею право его стереть.
305: И это всегда право, у меня есть. Если мне передали указатель, я могу освободить память, как только вы куда-нибудь передаёте указатель, и это фантастически сильный аргумент, который мы не привели на том слайде.
306: Где мы должны были его привезти? У меня по этому указателю могут удалить, а по ссылке не могут. Правда, от ссылки могут взять указатель и уже по нему удалить. Но там человек не сможет быть уверен, что он, что он делает правильную вещь, потому что
307: Если я передаю ссылку на int, этот инт может не быть выделен да, вот мало того если у меня есть указатель и я беру вот так что я вообще сделал да вот.
308: То у меня получается, у меня получается нечто ужасное, но вызвать фотку я могу вызвать 1 птр я могу, а в бар не могу, потому что у констре есть инвариант, инвариант, констант, референс, следующий под
309: Правильное целое под констант референс, валидное целое целое под констант референс. За исключением некоторых случаев, вы не можете испортить. Оно может само испортиться, но вы не можете испортить его интерфейсом этого кон референс.
310: И не вам принадлежащее. Именно поэтому побитовое представление ссылки скрыто от программиста. И важное замечание об инкапсуляции у нас, к сожалению, немножко заканчивается время. Я хотел оставить на выдачу сразу 2 домашнего.
311: Задания я люблю давать домашние задания сразу в начале курса, чтобы вы весь год их делали. Ну, кое-что я выдаю зимой уже, да, но первые 2, 3 я люблю давать почти сразу, чтобы вы могли выбирать. Так вот, когда
312: Вы пишите шаблон класса, и вы делаете у него приватное состояние. Вы очень часто рассчитываете на то, что его методы смогут с ним работать. И это правда, они смогут, но
313: Инкапсуляция это не свойство объектов типа инкапсуляция это свойство. Типа, смотрите, вот у вас есть шаблонный класс лист, вот у него есть закрытое состояние нодт указатель топ бэк.
314: В методе канкат вис вы можете просто писать other точка топ и вот этот объект other он такого же типа внутри которого вы сейчас и поэтому его топ для вас открыт видите?
315: Он такого же типа, он не вы, он не this.
316: Но он такого же типа.
317: Как это сломать? А вот так, если я передам его такого же типа, но с другим шаблонным параметром?
318: То он другого типа.
319: Тип, параметризованный другим параметром, это другой тип. И если вы передаёте сюда лист у azer, то это нарушение инкапсуляции.
320: Ещё раз инкапсуляция с помощью полей прайвет паблик не имеет отношения к физическим объектам, вот этот физический объект other вот на этом слайде не имеет значения, что он не вы, а вот на этом слайде не имеет значения, что он тоже листик.
321: Имеет отношение только к 2 вещам, к типам и к именам. Вы можете использовать имена внутри методов. Типа все вот это про что модификатор правит, он больше ни про что.
322: И, разумеется, инкапсуляция делает критически важными конструкторами, потому что если у нас прайвет, то состояние объекта нельзя установить извне.
323: Теперь мы обязаны устанавливать его конструктора.
324: И мало того, состояние объекта нельзя не просто установить извне, его нельзя и очистить извне. И поэтому, чтобы очищать состояние объекта, мы должны писать деструктор, деструктор выглядит как конструктор, но начинается с тильды мы поподробнее поговорим о
325: Деструкторах довольно скоро, пока что просто деструктор это такая функция, которая вызывается в конце жизни.
326: Вот, давайте.
327: На этом остановимся. В следующий раз мы поговорим о динамической памяти, потому что проблема, как сказать, клиффхэнгер, к следующему разу это молок и фри. Молок и фри ничего не знают о вызове конструкторов. Да, их придумали во времена языка си.
328: Если у вас теперь есть объект, состояние которого вы можете установить только конструктором, то как же вы будете его выделять на куче? Мы об этом. Мы начнём об этом разговор в следующий раз. Кроме того, в следующий раз я познакомлю вас с мёртвым попугаем.
329: Мой, мой друг мёртвый попугай, который дальше будет сопровождать нас, весь этот курс, значит, домашнее задание.
330: 2 домашняя работа, которую я тоже ожидаю в параллель с 1 только не присылайте 2 в 1 письме да вот она называется хв 3 д и хв 3 д. Очень простая домашняя работа.
331: Вам очень понравится со стандартного ввода приходит число, а потом н наборов точек, представляющих только не двумерные, а для интереса трёхмерные треугольники.
332: Треугольники. А что могут быть не плоскими? У вас линейная алгебра была, вот, соответственно, представляющих трёхмерные треугольники, то есть треугольник с вершинами в
333: Пространстве, как угодно лежащими. Ну да, треугольник плоский. Сложно представить себе не плоский треугольник. Задача вывести номера всех треугольников, которые пересекаются с каким-либо другим треугольником. Например, если у вас есть треугольники,
334: 1, 2 и 3 и 1 пересекается с 3, то вы вводите 1 и 3.
335: Отлично. Соответственно, небольшой небольшой обзор литературы. Во первых, в этот момент, начиная с этой лекции, вы можете начинать читать гради буча, объектно ориентированный анализ и проектировании.
336: С приложениями на силас плас гради буч в своё время произвёл на меня отличное впечатление. Там довольно мало сипла плас, там довольно много объектно ориентированного анализа и проектирования. То есть это книжка, которая определяет важные термины, я их
337: Тоже, конечно, определю, но я их определю немножко по своему, а она их определяет, как принято в мире. Инкапсуляция, полиморфизм, наследование, вот это все и примерно рассказывает, зачем это нужно. Но опять-таки это рассказывается по своему. Вот эта книжка, она такая.
338: Немножко, я бы сказал, такая гуманитарная, она похожа на учебник философии там, или вот учебник истории. То есть там мало кода, там много рассуждений можно читать на досуге. И если кому-нибудь не хватает, не хватает.
339: Линала. Я очень рекомендую гильберт, стренг, интродакшн, Тулин алгебра, между прочим. Между прочим, я не знаю, как вас учат линалу, но, с моей точки зрения, вас учат. Ему хорошо, но не ту.
340: Да, потому что вас учат доказывать всякие теоремы и все такое, но не развивают базовую интуицию. Вот просто базовую интуицию. Вот, а стренг в своих лекциях развивает именно базовую интуицию. Если хотите, вы можете найти
341: Курс гильберта стренга на YouTube вот у него записаны лекции потрясающее я вот я был счастлив послушать этот курс уже сильно после окончания института, когда я думал, что я знаю линал очень хорошо и вот это.
342: Замечательная книжка геометрик тулс фо компьютер графикс 2002 это, конечно, не количество страниц, но где-то около того вот если будут интересны какие-нибудь ещё клёвые алгоритмы из мыслительной геометрии, особенно для высоки.
343: Уровней 2 задания, где они будут нужны. И напоследок небольшой Каан в 1 монастыре был монах, который постоянно в своих методах нарушал инкапсуляцию, постоянно делал в классах открытые поля и
344: Когда его спрашивали, говорил, что так просто быстрее, быстрее доступаться к методу, к полям. Вот, и ему не нужно тратить время на вызов метода. Он может сразу записать что-нибудь в поле. Вот и настоятель монастыря позвал его в свою келью и ска.
345: Сказал за то, что у тебя такой продуктивный подход к производительности позволь мне угостить тебя рисом, ложись на пол. И монах спросил, почему на пол и tell, сказал ну как, я разрежу тебе живот, насыплю туда рис так же будет гораздо быстрее. Так вот.
346: Вот есть 2, 2 фундаментальные ошибки, которые может сделать программист. Я хочу предостеречь вас от обоих. 1 фундаментальная ошибка не сделать инкапсуляцию там, где она нужна. И вто.
347: Фундаментальная ошибка сделать инкапсуляцию там, где она не нужна, например, класс точки. Зачем вам инкапсулировать в точке икс игрек? Какой вариант вы хотите соблюдать, да, то есть там, где она нужна, вы её делаете там, где
348: Она не нужна, вы её не делаете. Вопрос.
349: Вопрос был есть ли реальный способ разделить шаблонный класс на точка аш точка файл отдельная компиляция шаблонов запрещена вопрос есть ли способ разделить на точка аш точка sp файлы, шаблоны, раздельная компиля?
350: Шаблонов запрещена. Вот, но как сказать,
351: Варианты есть, скажем так, варианты есть. Давайте считать, что варианты, варианты этого сделать вам пока не нужны. То есть пока что вы все определения всех методов любого вашего шаблонного класса просто пишите в
352: Хедере так делают все во всем мире, возьмите буст, почитайте в c plus plus люди обожают хедер, он ли библиотеки? Вы берете все методы, все определения выносите в хедер, у вас инкапсуляция достигается другим у вас?
353: Достигается модификаторами, правит паблик. Вам просто не нужно ничего прятать в модуль. Соответственно, просто пишите все в хедере и все. А о методах как это распределять и как это инстанцировать и трата та, мы поговорим во 2 части.
354: Ещё вопросы?
355: Это минимальный размер как тогда компилятор работает с char, это минимальный адресуемый размер как компилятор работает с битовыми полями, те кто был у меня на 1 курсе знают компилятор работает с битовыми полями с помощью побитовых операций, такие как beat.
356: Сдвиг, например, что вы делаете, когда вы делаете битовый сдвиг, вы сдвигаете значение, правильно? То есть у вас значение лежит по тому же адресу. Просто вы, грубо говоря, там разделили его на 3 или умножили на 3, да, и его биты теперь выстроились по дру.
357: Ну, не на 3, на 2 в степени 3, да, вот. И дальше вы читаете его бит. То есть для того, чтобы работать внутри байта, компилятору нужно работать со значениями, а вот адресовать компилятор может только byte, ну.
358: Мысли, только чары.
359: Это хороший вопрос, ещё вопросы?
360: Больше вопросов нет. Тогда я, наверное, сейчас выключу. Оо, тоже ничего нет. Тогда у меня. Все, всем спасибо.