Sobes.tech
Middle+

Ինչ եք իմանում բացառությունների անվտանգության երաշխիքների մասին?

sobes.tech AI

Պատասխան AI-ից

Անվտանգության երաշխիքները սահմանում են ֆունկցիայի վարքագիծը բացառության առաջացման դեպքում: Կան չորս մակարդակի երաշխիքներ:

  1. Հիմնական երաշխիք (Basic guarantee): Եթե ֆունկցիան նետում է բացառություն, ծրագրի վիճակը մնում է վավեր: Հաշվարկային ռեսուրսները չեն կորցվում (օրինակ՝ հիշողությունը ազատվում է), բայց օբյեկտների ճշգրիտ վիճակը կարող է անհայտ լինել: Շարունակել գործել հնարավոր է:

    // Հիմնական երաշխիքի օրինակ
    void basic_guarantee_function(std::vector<int>& vec, int value) {
        // Միգուցե առաջանան բացառություններ ավելացման ժամանակ
        vec.push_back(value); 
        // Եթե առաջանա բացառություն, vec-ը կարող է լինել անկանխատեսելի վիճակում (մի մասամբ փոխված),
        // բայց հիշողությունը, որը հատկացվել է vec-ի համար, ճիշտ կերպով ազատվում է ելքի ժամանակ:
    } 
    
  2. Կոշտ երաշխիք (Strong guarantee): Եթե ֆունկցիան նետում է բացառություն, ծրագրի վիճակը մնում է նույնը, ինչ նախքան ֆունկցիայի կանչը: Բոլոր փոփոխությունները վերացվում են:

    // Կոշտ երաշխիքի օրինակ
    // Օգտագործում ենք Copy-and-Swap մեթոդը կոշտ երաշխիք ապահովելու համար
    class Resource {
        int* data;
        size_t size;
    public:
        Resource(size_t s) : size(s), data(new int[s]) {}
        ~Resource() { delete[] data; }
        Resource(const Resource& other) : size(other.size), data(new int[other.size]) {
            std::copy(other.data, other.data + size, data); // Միգուցե առաջանա բացառություն
        }
        Resource& operator=(Resource other) // Վերցնում է արժեքով, ինչը առաջացնում է կոպիա
        {
            swap(*this, other); // Չի առաջացնում բացառություններ
            return *this;
        }
        friend void swap(Resource& first, Resource& second) noexcept {
            using std::swap;
            swap(first.data, second.data);
            swap(first.size, second.size);
        }
        // ... այլ անդամներ
    };
    
    void strong_guarantee_function(Resource& res, size_t new_size) {
        Resource temp(new_size); // Եթե այստեղ առաջանա բացառություն, res-ը չի փոխվի
        res = temp;               // Օգտագործում է վերագրի օպերատորը, որը ապահովում է կոշտ երաշխիք
    }
    
  3. Բացառությունների բացակայության երաշխիք (No-throw guarantee): Ֆունկցիան հաստատապես չի նետում բացառություններ: Այդպիսի ֆունկցիաները նշվում են noexceptSpecifier-ով:

    // Բացառությունների բացակայության օրինակ
    void no_throw_function() noexcept {
        // Ոչ մի գործողություն, որը կարող է առաջացնել բացառություն
        int a = 5;
        int b = 10;
        int c = a + b;
    }
    
  4. Անհաջողության երաշխիք (Failure guarantee): Բացառությունների անվտանգության կոնտեքստում երբեմն նշվում է այս մակարդակը, որը նշանակում է, որ ֆունկցիան կարող է թողնել ծրագրին անորոշ վիճակում, ռեսուրսների կորուստ կամ սխալներ։ Սա իրականում բացակայում է երաշխիքների։ Պետք է խուսափել նման վարքագծից:

Բացառությունների անվտանգության երաշխիքների կարևորությունը կայանում է հուսալի և կանխատեսելի կոդ ստեղծելու մեջ, որը ճիշտ կերպով է մշակում սխալները և կառավարում ռեսուրսները նույնիսկ բացառությունների առաջացման դեպքում: Ելքի մակարդակի ընտրությունը կախված է գործողության կարևորությունից, վերականգնման արժեքից և բացառության առաջացման հավանականությունից:

Համեմատական աղյուսակ երաշխիքների մասին:

Երաշխիք Կարգավիճակ բացառության դեպքում Տվյալների ամբողջականություն Ռեսուրսների կորուստ
Հիմնական Վավեր, բայց անորոշ Չի երաշխավորվում Չի կա՛նք
Կոշտ Չի փոխվում (ինչպես նախքան) Ուրիշ է պահվում Չի կա՛նք
Բացառությունների բացակայություն Երբեք չի լինում (չի լինում բացառություններ) N/A N/A
Անհաջողության (չի լինում) Անորոշ, հնարավոր է վնասում կամ սխալներ Չի երաշխավորվում Մոտավոր է