Transcript for:
C++ Lesson: Constructors and Copying

Вітаю на уроці c++ Сьогодні ми з вами розглянемо три важливі концепції які розширть ваше розуміння об'єктно орієнтованого програмування та дозволять вам створювати більш потужні та динамічні програми перше - це делегування конструкторів що дозволяє одному конструктору викликати інший конструктор цього ж класу для ініціалізації об'єкта та поліпшення підтримки коду друге це в нас буде показчик зс показчик - це вказівник на поточний об'єкт нашого класу який використовується для доступу до його внутрішніх компонентів ми розглянемо його як використовувати зіст для уникнення конфлікта імен і третій не менш важливий - це конструктор копіювання дозволяє створювати копію об'єкта класу ми дізнаємося як цей конструктор працює коли Та чому його потрібно використовувати почнемо з делегування конструкторів як було сказано раніше делегування констру нструкто це можливість викликати в одному конструктору інший конструктор цього класу якщо пам'ятаєте з попередньої уроку В нас може існувати декілька конструкторів конструктор - це метод який викликається при створенні об'єкта в класі може існувати декілька конструкторів такого відповідного класу конструктор має ім'я нашого класу може приймати параметри і нічого звісно він не повертає і займається звісно для ініціалізації значень конструктор потрібно точні делегування конструкторів потрібно використовувати зі списковою ініціалізацією минулого разу ми також розглядали з вами Що таке спискова ініціалізація це От після закриваючи кругли дужки нашого конструктора ми ставимо дві крапки і ініціалізуємо наші параметри наші значення які там єсть І от в списковій ініціалізації можна застосовувати оце делегування нашого конструктора застосування конструктора я вам покажу на практичному завданні практичне завдання полягає в тому що потрібно створити лас person який представляє собою ім'я вік клас повинен мати два конструктора Один який приймає ім'я та вік та інший який приймає Лише ім'я в цьому випадку вік має ініціалізуватися значенням за замовченням нулю тобто якщо ми будемо викликати конструктор який приймає тільки ім'я то вік в нас буде ініціалізовуватись по замовчуванню нулем для цього ми будемо використовувати делегування конструкторів щоб допомогло нам уникнути якихось лишніх викликів методів розпочнемо реалізацію нашого класу person створюємо клас person person відкриваємо фігурні дужки ставимо крапка з коми в кінці пишемо ключове слово Public паic пам'ятаємо що специфікатор доступ паli надає нам можливість відкривати поля доступу тобто тепер ці поля які йдуть після нашого ключового слово Public являються відкрити і ми можемо звертатися до них через об'єкт нашого класу тобто створили об'єкт нашого класу і маємо можливість звертатися до відкритих полів нашого класу зазвичай у відкритих полях ми використовуємо це конструктори методи для якихось там завдань методпint метод наприклад setget і інші ну і звісно тут деструктори в полях privт ми з вами створюємо змінні властивості вони в нас закриті І так нам потрібно реалізувати відповідно можливість вказувати два значення це ім'я та вік створимо специфікатори доступу Private використовуємо специфікатор доступ privт і створюємо дві змінні перша змінна це буде в нас String name M name чому mname минулого разу не говорив mn - це префікс який буде відрізняти нашу змінну name і буде говорити що це являється змінна нашого класу int M H взагалі по стандарту кодування можна використовувати M А можна використовувати про просто нижнє підкреслення але якщо наша зміна там складається з двох слів то ми використовуємо що перша змінна буде починатися точніше якщо змінна починається з двох слів то перше слово починається з маленької літери а друге слово починається з великої літери наприклад Антон та Антон Ну це так умовно що антонно там ім'я може бути як завгодно але покажу От якщо ми створиюємо змінну то вона в нас повинна виглядати Таким чином приберемо просто Антон нам потрібно тільки змінна не і тепер переходимо до реалізації конструкторів нам треба реалізувати конструктор клас повинен мати два конструктора Один який приймає ім'я та вік створюємо конструктор нагадаю конструктор має ім'я нашого класу відкриваємо круглі дужки він в нас приймає ім'я та вік пишемо STD String name кома in H далі через спискову ініціалізацію ми ініціалізуємо наші значення пишемо M name круглідужки name через кому mh круглідужки H і фігурні дужки сть Один який приймає ім'я та вік та інший який приймає Лише ім'я тобто Іще один нас буде конструктор один person який приймає Лише ім'я т то крапдкрапка СН name в цьому випадку якщо ми приймаємо тільки одне ім'я то ми ініціалізуємо вік по замовчуванню нулем і тут використовуємо делегування конструктору і тут тепер ми зараз будемо викликати наший конструктор який приймає два значення тобто якщо ми змогли застосувати конструктор тільки для того щоб передати ім'я Нам треба ініціалізувати по замовчуванню змінну h0м і плюс якось ініціалізувати змінну mname Наприклад ми могли б зробити що без делегування це буде без делегування от що ми могли зробити наприклад написати M name круглі дужки name потім через кому mh ну це також являється вірно але ми можемо викликати тепер інший конструктор нашого класу і скористатися делегуванням ми це при ємо після двокрапки пишемо person відкриваємо круглі дужки передаємо туди name і передаємо туди нуль в такому випадку ми викликаємо конструктор верхній який має можливість приняти прийняти ім'я та вік і потім в свою чергу він буде в своїй списко ініціалізації ініціалізувати наші змінні mname і mh оце і являється іалегуванням конструкторів тобто можливість викликати конструктор такого ж са самого класу точніше конструктор цього ж класу який вже існує або коли ми будемо розбирати з вами спадкування або навіть якщо ми будемо створювати всередині класу ще об'єкт одного класу ми також маємо можливість в спискові ініціалізатиї викликати конструктор іншого класу для того щоб ініціалізувати ці дані це більш детальніше будемо розбирати коли приступимо до вивчення спадкування там така можливість також є застосування алегування конструктора але поки що вам достатньо запам'ятати і зрозуміти що ми маємо можливість самостійно викликати цей конструктор самостійно тому що пам'ятаєте я вам нагадував Що автоматично відбувається виклик конструктору на етапі створення об'єкта коли ми будемо створювати об'єкт передавати тільки одне ім'я то в нас буде автоматично викликатись цей конструктор але в спискої ініціалізації ми Прописали цього ж конструктора виклик верхнього конструктора який приймає в нас name та H і в свою чергу ми передаємо name і нуль вони потрапляють змінну сюди name цей нуль потрапляє сюди в H і потім через спискову ініціалізацію ми ініціалізуємо mname і H відбувається такий ніби ланцюжок викликаємо конструктор передаємо ім'я потім викликаємо ще один конструктор передаємо ім'я нуль от цей конструктор викликається він отримає ім'я і нуль а потім ми нейм кладемо сюди а нуль кладемо сюди от така реалізація застосування делегування конструктора давайте додамо метод Void print для того щоб вивести і про застосувати наші конструктори print протестити наші конструктори const відкриваємо рні дужки STD C Out пишемо name двокрапка виводимо змінну name крап H двокрапка і виводимо змінну H mh STD кра реалізуємо intm відкриваємо фігурні дужки створюємо об'єкт нашого класу пишемо person О1 застосуємо конструктор з двома параметрами передамо наприклад Антон N лишню приберемо кома і вік 20 наприклад і для такого об'єкта О1 викличемо метод print крапка скою скомпілюємо Зараз нашу роботу компілюємо Угу До речі забув сказати що делегування конструктора нас відбувається по стандарту 11-го року тобто він був введений в стандарті c++ 11го року той хто працює на Visual studі в відесистемі Там зазвичай всі Visual studі вони використовують c++ найновішого стандарту Мені тут потрібно буде компілювати з певним флагом для того щоб все відпрацювало коректно я пишу STD = c++ 17 використовую стандарт 17-го року а відповідно в 17й рік уже включений і 11-й рік компілюємо Так в нас дві десь два мейна заховалося угу так це наступна робота яку для вас підготував ми її зараз закоментуємо там було два мейни тому виникав конфлікт компілюємо повторно помилки немає запускаємо виводимо name Anton H20 все працює коректно Тепер давайте викличемо ми а конструктор який приймає один параметр О2 передамо ім'я крапкомою і викличемо для O2 також metтоod print крулідужки крапка скомою компілюємо повторно запускаємо виводимо name Anton H1 точніше 20 потім виводимо name Сергій і h0 тобто тут ми викликали з вами конструктор Який в нас сприймає тільки ім'я але в свою чергу він виконує делегування передає задачу ініціалізації змінним іншому конструктору який приймає два параметри nameм і по замовчуваню нуль і в свою чергу він уже займається ініціалізацією змінних от що таке у нас з вами делегування конструкторів тепер перейдемо Давайте до вказівника зізщ нагадаюмо вказівник зіст - це вказівник на поточний об'єкт нашого класу він використовується для доступу до його внутрішніх компонентів ми розглянемо його застосування для того щоб уникнути конфлікту імен уявимо собі що в нас є от програма єсть точніше клас myкла в ньому естьсть конструктор Get datata і одна змінна змінна називається int datata Перепрошую Це не конструктор помилився це в нас метод setter пам'ятаєте сеter нам потрібни для того щоб встановлювати значення getter для того щоб повертати значення от для нас тут реалізований сетер сетер який встановлює значення для нашої змінної даa сетер нагадаю це метод Точніше це функція це як функція ми у функцію передаємо якесь значення в неї тут в круглих дужках створюється аргумент ще одна змінна вона отримує цю інформацію і потім цю зміну ми використовуємо для того щоб ініціалізувати іншу змінну яку ми хочемо а інша змінна - це змінна нашого класу тут зараз вже застосовується вказівник зіс Як бачите це ключове слово зіс вказівник на об'єк якщо використовуємо вказівник ми використовуємо стрілочку для того щоб звернутися до внутрішніх компонентів нашого класу і потім равно даa для чого тут він використовується тому що в нас з вами без його застосування буде виникати конфлікт імен чому полягає конфлітки мен тому що коли ми викликаємо метод Set datata передаємо значення передали змінну дати якусь інформацію а потім пишемо дата равно дата то пріоритет застосування змінної з ім'ям дата буде відповідно відноситись більше до змінної оцієї яку ми створили круглодужка тому що ця змінна створюється локально і вона має більший пріоритет над змінною яка створюється в нас на рядку номер 65 і тому коли я пишу дата Рівне дата то я роблю самоприсвоювання оції змінні дата яка в мене От створюється в круглих дужках тобто аргумент мого метода Set datata в int menю ми з вами створюємо об'єкт через об'єкт викликаємо метод се дати передаємо значення для ініціалізації потім через C Out хочемо викликати metмеthod Get datти і повернути це значення якщо ми будемо зараз якщо ми залишимо так програму попробуємо її скомпілювати і запустити ми виводимо якесь сміттєве значення тобто бачите великий набір цифр точно не 42 Я хотів би вивести 42 тому що я використовуюся Data для встановлення значення змінної Data потім використовую Get Data для того щоб повернути значення gata відповідно я планую повернути 42 як я кладу але так як всередині функції Set datata буду говорити метод всередині метода Set Data в нас створюється змінна int Data яка має таке ж саме ім'я як змінна яка знаходиться всередині нашого класу і коли я пишу дата рівна дата то я не присвоюю значення цієї змінної сюди Я присвоюю відповідно ці ж змінні саму себе от цієї змінні відбувається самоприсвоювання між цією змінною локальною тому якщо потрібно в деяких випадках уникнути конфлікту імен ми можемо використовувати оцей внутрішній вказівник зїз внутрішній вказівник зїз він вказує не внутрішні елементи нашого класу це і змінні це і методи якщо я напишу зіс і поставлю стрілочка то бачите що я маю можливість вибирати внутрішні компоненти нашого класу Чи це змінна Чи це метод дата чи се дата нам потрібна змінна дата це означає що Я уточню з яким компонентом я буду тут працювати я буду працювати з цією змінною і тепер коли я пишу зіз стрілочка дата равно даa Я беру інформацію яка зберігається в цій змінні даa от вона тут присвою і беремо присвоюємо змінну дата на рядку номер 65 зберігаємо зміни робиуємо знову скомпілювати скомпілювалась програма запускаємо даa 42 працює тепер все коректно зіст можна використовувати для того щоб от уточнювати а його можна використовувати всередині методів але не можна використовувати в середині дружні функції коли будемо з вами розпочинати ее вивчення перевантаження операторі ми там будемо застосовувати дружні функції і там його відповідно використовувати не можна Тобто можна використовувати вказівник зіс тільки всередині класу або всередині методів класу якщо ми наприклад будемо виносити реалізацію метода за межі класу Я показував також минулого разу то ми можемо так само тоді а в тому ж самому методі який знаходиться реалізований за межами класу використовувати наш вказівник зс тільки у внутрішніх компонентах ну і звісно зс - це вказівник і він собі зберігає адресу яку ж там що ж там за адреса це адреса нашого поточного об'єкта Object це адреса нашого об'єкта нагадаю що всі елементи чи то змінна чи то з масив чи то об'єкт Вони мають адресу е де вони зберігаються в пам'яті і відповідно вкаціівник зіст він зберігає цю адресу оцього об'єкта от ми створили objectject відповідно я можу дізнатись його адресу або через аampersн або наприклад написати метод а це в нас буде повертатися адреса пишемо zis будемо просто виводити в Void Void Get ptr круглі дужки фігурні дужки STD C Out і виводимо зс stdel.s і розміновимо попробуємо без розмінування вивести значення викликаємо метод пишемо Object крап вибираємо getptrкра компілюємо запускаємо от ми вивели з вами адресу це адреса нашого об'єкта objectgptr це ми вивели адресу нашого об'єкта от що таке вказівник якщо пам'ятаєте з попередніх попередніх уроків то вказівник - це зміна яка зберігає відповідно собі адресу але в класі вона застосовується трішки по іншому має можливість вказувати на внутрішні компоненти нашого класу і плюс зберігає адресу поточного об'єкта з яким ми працюємо і тепер переходимо до більш цікавішого це конструктор копіювання що таке конструктор копіювання ну конструктор вже Зрозуміло так що це метод який автоматично викликається при створенні об'єкта але що значить конструктор копіювання конструктор копіювання - це нас особливий конструктор в мові c++ який використовується для створе нових об'єктів як копія існуючого тобто коли ми з вами будемо створювати об'єкт нашого класу і його будемо ініціалізовувати наприклад не int value не якимось цілочисельним значенням а об'єктом такого ж самого класу який вже ми створили раніше То буде викликатися конструктор копіювання от він для чого предзначени він копіює один об'єкт для створення іншого об'єкта копіює дані розберемо приклад пам'ятаєте коли показував вам створення об'єкту так давайте ще раз От створю коopі О1 відкрую круглі дужки то в нас позамовчуванню додається конструктор копіювання тут ми реалізували його самостійно тому він буде підтягуватись Але якщо ми не будемо його реалізовувати самостійно а захочемо наприклад давайте цей клас розкоментуємо зараз захочемо подивитися чи існує цей конструктор то по замовчуванню в нас додається і конструктор копіювання і конструктор переміщення в попередніх уроках я це вже про про це напевно говорив створимо об'єкт My Class О1 відкримку глядушки О В нас три конструктора але відповідно В нас немає ні жодного конструктора всередині класу Що ж то за три конструктора дивимося конструктор по замовчуванню завжди також додається всередину класу конструктор копіювання con My Class ersant це конструктор копіювання ми зараз будемой розбирати і ще існує конструктор переміщення яке Ми також в подальших наших уроках розберемо тобто по замовчуванню якщо ми не реалізуємо ці три основні речі навіть чотири це ще оператор присвоювання Повторюю це чотири конструктор по замовчуванню конструктор копіювання конструктор переміщення і оператор присвоювання то вони по замовчуванню додаються і в них там сама примітивна реалізація по замовчуванню Вона працює коректно тільки з статичними даними з динамічними даними вона працювати не буде я вам також все продемонструю І так от повертався до нашого наступного прикладу назви використовується вже самостійно реалізований конструктор копіювання по самовченю він так і виглядатиме в нас є клас копі в ньому єсть змінна дата єсть конструктор який отримує значення intве ініціалізує нашу змінну дата в ньому єсть sprндата який виводить просто значення і от конструктор копіювання конструктор має таке ж саме ім'я ко але цього разу він приймає не intвеue а приймає об'єкт Цього ж самого класу const Copy enasa прийняв об'єкт Цього ж самого класу і далі ми пишемо Data enза Data нашу змінну даa ми ініціалізуємо датою яка знаходиться в об'єкті еназа яким ми будемо використовувати дивимося в intm в імені Ми створюємо об'єкт Object 1 його ініціалізуємо значенням відповідно 42 далі Ми створюємо ще один об'єкт Object 2 це Ми видалимо створюємо Object 2 відкриваємо круглі дужки і тепер ми тут кладемо з вами не 42 не якесь цілочисельне значення а ми кладемо об'єкт такого ж самого класу об'єкт який вже був створений і це означає що я хочу скопіювати дані які зберігаються в цьому об'єкті Object 2 і покласти їх в Object в Object 1 відповідно дані взяти скопіювати і покласти в Object 2 Object 2 в нас створюється тільки тому тут застосовується конструктор копіювання тому що нагадаю ще раз конструктор копіювання в нас викликається тоді коли ми тільки створюємо наш об'єкт і тут в нас викликається конструктор копіювання збережемо змінні скомпілюємо нашу роботу запускаємо виводимо даa 42 і виводимо Data 42 вивели метод print е точніше викликали метод print Data для обжекта 1 і потім викликали метод print для обжекта 2 Як бачите в обj 2 також тепер зберігається значення 42 тому що ми застосували конструктор копіювання скопіювали всі дані з обжекта о в objectкт 2 а оглядання а як виглядає оця дія копіювання от Таким чином реалізується конструктор копії тут приймається в нас константний об'єкт тому що ми його змінювати не будемо І ми не повинні його змінювати приймаємо об'єкт такого ж самого класу con enas через спискову ініціалізацію ініціалізуємо нашу зміну Data але тепер замість А ми пишемо enза Data enaz - це наш об'єкт А так як ми знаходимося всередині класу ми можемо через об'єкт напряму звертатися до змінної пишемо enaz. Data звертаємося до змінної дата беремо звідси інформацію і кладемо змінну дата і тепер наш поточний об'єкт який ми от створюємо Object 2 він був ініціалізований от його змінна ініціалізований змінною дата яка знаходилась в enназа А enза - це наш обкт 1 і відповідно ця змінна дата була ініціалізована в свою чергу 42 за допомогою оцього конструк От так в нас відбувається застосування конструктора копіювання є ще ще один спосіб застосування конструктора копіювання це коли Ми створюємо також об'єкт нашого класу копі наприклад О3 і пишемо а О2 Ну хай буде О3 і пишемо Object 2 крапка з комою коли Ми створюємо об'єкт таким чиномкори стоє операцію присвоювання тут у нас також буде викликатися конструктор копіювання використовуємо для обжекта 3 metthod print Data крапка з комою компілюємо запускаємо дата 42 дата 42 і даa 42 от вивели третій раз дата 42 для от нашого об'єкта О3 Перший спосіб коли ми використовуємо ініціалізацію при створенні використовуємо круглі дужки і в кругли дужках ми прописуємо наший об'єкт який хоче скопіювати другий спосіб - це коли ми створиємо знову об'єкт О3 і пишемо присвоювання і знов копіюємо об object2 хотів сказати Object O2 і є ще також два способи застосування конструктора копіювання точніше два способи коли він буде викликати з той конструктор копіювання перший - це коли ми маємо функцію Void F і в таку функцію будемо передавати об'єкт нашого класу ко Cop О1 крап STD навіть будемо просто 1 точка print datata Коли я буду викликати функцію якусь І передавати дивимося що об'єкт типа самостм з елементом функції коopі print Data const copі коopі о один в нас не існує давайте приберемо коst глянемо підкреслюється залишимо конст попробуємо скомпілювати зараз подивимося як відпрацює наша програма можливо просто не передаю Ніякий об'єкт пишемо F передаємо туди o3 крапка С компілюємо роботу виникає помилка з arгумен not member function print Data prнта О1 копі в нас копія есть копії О1 так чомусь О1 не хоче в нас знаходити метод а який взагалі там метод ти можеш знайти нам О1 точка Ніякий якщо ми просто о напишемо пишемо О крапка цікаво в чому трапилась проблема добре Ми зараз її вирішимо Void F cont Cop o1 обject візьмемо objectject Я не впевнений що це в імені проблема але все ж таки пка скома Ні це не імені проблема об'єкт содержить кваліфікатор типа const copі А якщо по посиланню передати функція F невже в мене ще десь існує функція F навряд чи що нуще функція F давайте назвемо print викликається функція print хочу викликати об'єкт посилання приберемо виникла проблема В нас objectject точка це закоментував не хоче в нас викликати внутрішній об'єкт ми знаємо і про існування нашого класу знаємо про існування функції передаємо неї об'єкт копії требується точка запятої Ні не потрібно заптою зараз ще раз скомпілюємо скомпілювали проблем Ніяких немає Гаразд пишемо Object точка Угу Окей будемо просити допомогу нашого біто erнчеck перевірть будь ласка що ми тут не так написали тут вірно параметр функції прин по значею Что может привести ненужному копируваню объекта чтобы избежать этого можно передвать параметр посилки Ні нам треба застосувати копіювання і щоб викликати конструктор копіювання але в чому проблема Чому чому він на не хоче підкреслює помилку тут скопіюємо цей рядок зараз перемістимо print Data скопілюємо ще раз скомпілювалося дуже дивно помилка зникла чи ні ще раз [музика] компілюємо приберемо конс добре воно скажеться на const print Data компілюємо скомпілювалося дуже дивно що скаржись на конст Хоча не повинно було скаржитися ну додам ще раз ко на ні скаржеться на конst о об'єкт константний Угу якщо не помиляюсь Треба щоб все пресувало то можна додати щоб метод приint також константний буде і тоді помилка думаю в нас пропаде да єсть виправили більш всього що коли ми в нас був константний об'єкт ми викликали метод print він був неконстантний в нас а метод приint якщо додамо кон То це означає що все середині нього Ми нічого змінювати не можемо і тоді все працює коректно Ну гаразд проблему Ми вирішили Тепер давайте рухайтись далі покажу вам застосування цього ж конструктора копіювання я додам тут для вас щоб ви бачили що коли ми передаємо без посилання а просто просто Таким чином по значенню наш об'єкт То буде для нього викликатись конструктор копіювання беремо цей рядочок скопіюємо stdleкраsom компілюємо повторно запускаємо дивимося тепер де нас викликається конструктор копіювання раз викликався конструктор копіювання потім в нас це на рядку 118 потім в нас два методи print Data викликаються ми виводимо значення другий раз викликається конструктор копіювання ми от виводимо потім знову виводимо значення дата 42 викликаємо функцію print в неї передаємо об'єкт О3 сюди передаємо цей об'єкт і тут відбувається копіювання також викликається конструктор копіювання і потім всередині цієї функції ми з вами знову виводимо значення дата 42 Як бачите в нас при передачі У функцію по значенню без посилання або безка ввника а просто позначені хто пам'ятає коли ми розбирали функції то там якщо ми маємо три способи передачи інформацію функцію по значенню по посиланню по вказівнику по значенню це означає копію відповідно коли ми передаємо по копії то передається нас копія такого об'єкта а тут створюється такий об'єкт і він починає ініціалізовуватися тим об'єктом який Він отримує і для того щоб ініціалізувати цей об'єкт іншим об'єктом виклика викається відповідно ж конструктор копіювання викликався конструктор копіювання відбулось копіювання даних і ми далі виводимо цю інформацію От і це в нас був другий спосіб хотів показати коли ми передаємо функцію а третій спосіб коли ми повертаємо з функції також об'єкт нашого класу наприклад ви створили а коopі тут створили ще один об'єкт отак будемо писати навіть абстракт не будемостворювати об'єкт return copі 55 крапка з комою тепер ми виводимо те що нам поверне оцей абстрактний об'єкт пишемо print круглі дужки знов об'єкт О3 точка printdata кра круглі дужки крапконі тому що додамо ще STD endel коли ми будемо передавати абстрактний об'єкт Тобто ми тут не даємо назву об'єкту Ми створюємо об'єкт він в нас абстрактний без імені ми його повертаємо з функції всередину intm тут ми його з вами підхоплюємо і для нього виводимо значення print datта відразу і він тоді далі нас видаляється але побачите що коли ми будемо повертатись функції цей об'єкт то тут буде відбуватись конструктор копіювання компілюємо не подобається що підкреслюється кутові дужки але ми зараз попробуємо це а скомпілювати все ж таки можливо оператор немає оператора виведення через C тому тут c і не потрібен для того щоб працювало все коректно бажано використовувати перевантаження оператора cта а в принципі тут ми нічого не виводимо Я чомусь написав то C Out ну бох з ним Ми його перебрали коли будемо розбирати перевантаження операторів я вам покажу як потрібно правильно реалізовувати перевантаження оператора cаut для того щоб правильно виводити інформацію нашого об'єкта навіть абстрактного об'єкта але тут ми повертаємо наш абстрактний об'єкт який був ініціалізований 55 ми його повертаємо з функції от викликаємо print повертаємо вразу і для цього абстрактного об'єкта який ми повертаємо ми йго нікуди не кладемо нікуди нікому його не присвою йому ми просто зразу хочемо вивести через нього метод print datata точніше застосувати через нього метод print datata компілюємо запускаємо конструктор копіювання відпрацював вивелось 42 і вивелось відповідно в нас 55 все спрацювало коректно от Як бачите ми можемо створювати відповідно і таким чином наш об'єкт абстрактний повертається він виводиться значення ну і тут по ідеї також повинно було у нас викликатися кон копію конст копія просат а наз Якщо я не помиляюся 42 і 55 42 це в нас звісно для цього О3 тут викликався конструктор копіювання І тут також має викли тесь конструктор копіювання повертаємо новий створений об'єкт Можливо коли ми створємо просто об'єкт не буде викликатися в нас абстрактний зараз Ми створимо інший попробуємо так зробити коopі О2 ініціалізуємо 55 крап з комою і передаме передамо О2 перекомпілюємо запустимо ні також не викликається тоді інший спосіб залишається самий простий це коopі o4 равно те що повертає в нас наший об'єкт приберемо тут ми метод print виклик нашого print datata і для o4 ми тепер викличемо його printdata кра компілюємо повторно запускаємо а 4255 і прин datта 42,55 консткопія не викликався конструктор копіювання більше всього або конструктор переміщення але теж не варіант що тут конструктор переміщення отут по ідеї точно мав би відпрацювати Зараз ми зробимо так круглі дужки візьмемо перевіримо ще раз компілюємо не викликається тоді можливо в чомусь помилився якщо в чомусь помилився і ви знайшли цю помилку то прошу будь ласка написати в коментарях я потім дам зворотню відповіді Ну і плюс Я ще для себе подивлюся чому ж тут в нас не викликався конструктор копіювання Гаразд приступимо до іншого прикладу застосування констру копіювання такий конструктор копіювання який я показав от він являється по замовчуванню і може коректно працювати з статичними даними але якщо вам потрібно буде використовувати роботу з динамічною пам'яттю то потрібно буде реалізовувати інший конструктор копіювання більш складнішу версію його це конструктор копіювання А для роботи з динамічною пам'яттю Чому Тому що коли ми будемо з вами АА скажемо так копіювати просто адреси наприклад в нас буде от об'єкт О1 ми будемо створювати копі О2 об'єкт його хочемо ініціалізувати О1 то в ньому буде відбуватися по покроково копіювання всіх да всіх даних наприклад буде в нас там вказівник якщо ми працюємо з динамічно пам'яттю зазвичай і sй і ми скопіюємо ці всі дані також вказівник для ptr2 Ну і Сай також Тото Ми беремо ось нашй об'єкт це значення нашого об'єкта О1 А це значення нашого об'єкта О2 відбувається копіювання покрокове Якщо об'єкт О1 в нас вказував на якусь динамічну комірку пам'яті То тепер виходить що і об'єкт О2 також буде вказувати на цю комірку динамічної пам'яті тому що два вказівника ptr і ptr в нас Вони відповідно мають тепер в собі одну і ту саму адресу ми взяли цю адресу скопіювали сюди і тепер наший обєкт О2 також вказує на одну комірку динамічної пам'яті але пам'ятаємо якщо ми працюємо з динамічною пам'яті то в класах Зазвичай ми реалізовуємо також з вами і деструктор для того щоб видаляти цю динамічну пам'ять і тут Коли ми почнемо видаляти за допомогою деструктора динамічну пам'ять і будуть знищуватися наші об'єкти ми зіткнемося з нашою проблемою проблема буде полягати в тому що в нас спочатку один об'єкт видалить цей участок динамічної пам'яті а потім наступний об'єкт також буде намагатися Видалити цей участок динамічної пам'яті і буде виникати проблема і ми детальніше вже розглянемо іншу реалізацію нашого конструктора копіювання для роботи з динамічною пам'яттю на наступному уроці Дякую вам за увагу і до наступного уроку до наступної зустрічі