Акылдуу көрсөткүчтөр
Үймөктөгү объекттер үчүн автоматтык, өзгөчө кырдаалга туруктуу ээлик
Негизги идея: Акылдуу көрсөткүч - бул үймөктө бөлүнгөн эстутумга ээлик кылган жана ээлик аяктаган учурда аны автоматтык түрдө бошотуучу стектеги кичинекей объект. Ар бир
new үчүн өз колуң менен delete дал келтирүүнүн ордуна, буну көрсөткүчтүн деструкторуна жасатасың. Бул эстутумга колдонулган RAII (Resource Acquisition Is Initialization): ресурстун жашоо мөөнөтү стектеги объекттин жашоо мөөнөтүнө байланган.
Аягында сиз төмөнкүлөрдү жасай аласыз:
- жылаңач
new/deleteэмне үчүн ишенимсиз экенин түшүндүрүү, - жеке ээлик үчүн
std::unique_ptrколдонуу жана аны жылдыруу, - биргелешкен ээлик үчүн
std::shared_ptrколдонуу жана анын шилтемелер эсептегичин окуу, - ээлик кылбай байкоо жүргүзүү жана шилтеме циклдерин үзүү үчүн
std::weak_ptrколдонуу.
1. Жылаңач new / delete көйгөйү
Сиз new менен үймөктө эстутум бөлүүнү жана delete менен аны бошотууну билесиз. Кыйынчылык - delete үчүн сиз жооптусуз, жана катачылык кетирүүнүн көп жолу бар:
- Агып кетүү (leak):
deleteунутуп калдыңыз, же эртеreturnаны өткөрүп жиберди, эстутум эч качан кайтпайт. - Илинген көрсөткүч:
deleteкылдыңыз, бирок көрсөткүчтү колдоно бересиз. - Кош бошотуу: эки код бутагы бир эле объектти
deleteкылат. - Өзгөчө кырдаалдагы агуу:
newмененdeleteортосунда өзгөчө кырдаал (exception) ыргытылат, ошондуктанdeleteаткарылбайт.
void process() {
Widget* w = new Widget(); // кол менен бөлүү
if (!w->load())
return; // КАТА: w агып кетет, delete аткарылбайт
w->run();
delete w; // унутуу оңой, же exception себеп өткөрүп жиберилет
}
Акылдуу көрсөткүчтөр тазалоону компиляторго жана деструкторго жүктөп, ушул катачылыктардын бүтүндөй классын жоёт. Акылдуу көрсөткүч стектеги объект болгондуктан, анын деструктору көрүнүү аймагынын аягында, ар кандай жол менен, анын ичинде exception стекти чечкенде да автоматтык түрдө аткарылат.