Sobes.tech
Middle+

Масъалаҳои эҳтимолии такрории истисно дар заминаи истифодаи сохтори 'дугонаи истисно'ро пешниҳод кунед.

sobes.tech AI

Ҷавоб аз AI

Дублӣ истисно (double exception) дар C++ вақте рӯй медиҳад, ки ҳангоми коркарди истисно (дар дохили блоки catch) як истиснои нав пеш аз анҷоми коркарди истиснои қаблӣ пайдо шавад. Ин ба даъвати std::terminate оварда мерасонад.

Масаланҳои чунин ҳолатҳо:

  1. Ифшои истиснои нав дар блоки catch:

    #include <iostream>
    #include <stdexcept>
    
    void func() {
        throw std::runtime_error("Истиснои аввал");
    }
    
    int main() {
        try {
            func();
        } catch (const std::runtime_error& e) {
            std::cerr << "Гирифт: " << e.what() << std::endl;
            throw std::logic_error("Истиснои дуввум дар catch"); // Истиснои нав
        }
        return 0;
    }
    

    Дар ин ҷо дар блоки catch, ки истиснои std::runtime_error-ро кор мекунад, истиснои нав std::logic_error фурӯ рехта мешавад.

  2. Истисно дар вақти тоза кардани захираҳо дар деструктор ҳангоми коркарди истиснои дигар:

    #include <iostream>
    #include <stdexcept>
    #include <vector>
    
    struct Resource {
        ~Resource() noexcept(false) { // Деструктор метавонад истисно кунад
            std::cerr << "Дастур кардани деструктор Resource" << std::endl;
            if (true) { // Шарт, ки истисно меорад
                throw std::runtime_error("Истисно дар деструктор Resource");
            }
        }
    };
    
    void risky_func() {
        Resource r; // Объект, ки деструктор метавонад истисно кунад
        throw std::runtime_error("Истисно аз risky_func"); // Истиснои аввал
    }
    
    int main() {
        try {
            risky_func();
        } catch (const std::runtime_error& e) {
            std::cerr << "Гирифт: " << e.what() << std::endl;
            // Ин ҷо метавонад истисно дар деструктор пайдо шавад, ҳангоми коркарди истиснои аввал
        }
        return 0;
    }
    

    Вақте risky_func истисно меорад, стекро канда мешавад. Дар вақти кандашавӣ, деструктор даъват мешавад. Агар ин деструктор истисно кунад, ҳангоми коркарди истиснои аввал, дуруст истиснои дучор мешавад.

  3. Истисно дар коркарди истисно бо сабаби хатоҳои дохилӣ ё функсияҳое, ки истисно меоранд:

    #include <iostream>
    #include <stdexcept>
    #include <vector>
    
    void process_error(const std::exception& e) {
        std::cerr << "Коркарди хато: " << e.what() << std::endl;
        if (e.what() && std::string(e.what()).length() > 20) {
             throw std::logic_error("Хатои дар коркарди паёми хеле дароз"); // Истиснои дуввум
        }
    }
    
    int main() {
        try {
            throw std::runtime_error("Ин паёми хеле дароз дар бораи хато"); // Истиснои аввал
        } catch (const std::exception& e) {
            process_error(e); // Ин даъват метавонад истиснои дуввумро ба вуҷуд орад
        }
        return 0;
    }
    

    Дар ин ҳолат, функсияи process_error, ки дар блоки catch барои коркарди истиснои аввал даъват мешавад, худ истиснои дуввумро ба вуҷуд меорад.

Дар ҳамаи ин ҳолатҳо, чун истиснои дуввум пеш аз анҷоми коркарди аввал (ё дар вақти кандашавии стек) пайдо мешавад, стандарти C++ даъвати std::terminate-ро талаб мекунад. std::terminate ба таври пешфарз abort()-ро даъват мекунад.