2015-08-20 19 views
6

Bir kapsayıcı için bir yedek yazı yazıyorum ve yerine tüm istisna garantileri yerine çalışıyorum. Şu anda clear yöntemini yazıyorum ve bir imha makinesinin bir istisna atıyor olsa bile, mümkün olduğunca tamamlamak ve her zaman tutarlı bir durumda kabı bırakmak istiyorum. Ayrıca temizledikten sonra, tercihen dilimleme olmadan istisnasını yeniden düzenlemek istiyorum.Bir istisna nesnesi ne zaman imha edilir (ve kontrol edilebilir)?

Bu bana soruya getiriyor; Bir istisna ne zaman imha edildi? Tek bir denemeye bakalım: Örnek için bu basitleştirilmiştir.

void container::clear() 
{ 
    bool had_exception = false; 
    std::exception* exp; 
    internal_set_empty(); // this cant throw 
    while(! internal_done()) 
    { 
     try 
     { 
      internal_destruct_next(); // this might throw if T::~T() throws 
     } 
     catch(std::exception& e) 
     { 
      had_exception = true; 
      exp = &e; 
     } 
    } 
    if(had_exception) 
     throw *exp; 
} 

ben istisna muhtemelen o ele dikkate alındığında tahrip çünkü bu, kötü başarısız bekliyoruz ve bu teknik olarak rethrow değil.

Başka bir girişim istisnanın bir kopyasını alırken, Dilim olmasını beklerim.

Özel durumun ömrünü uzatmanın bir yolu var mı? Böylece daha sonra yeniden düşünebilir miyim? Mümkünse, catch(...) aracılığıyla yakalanan istisnaları yeniden değerlendirmek istiyorum.

+0

http: // en.Senaryo çalışabilirse cppreference.com/w/cpp/error/exception_ptr kullanışlı olabilir. – Mat

+0

@Mat 'exception_ptr' tam olarak aradığım şey gibi görünüyor, ama daha temel bir sorun var gibi görünüyor. – sp2danny

cevap

4

yıkıcılar biri

Yapılamaz bir istisna atmak bile. Yıkıcılar bir sebepten ötürü değil, bir yıkıcı destekten kurtarılamaz. Yıkıcıyı attıran nesneleri temizlemek için hiçbir şey yapmıyorsunuz, çünkü bunu nasıl yapmaya bile çalışabilirdiniz ki, ama aynı zamanda onları zombi bir durumda asılı bıraktığınız anlamına geliyor.

Daha özel bir sorunuz olduğunda, öğelerin silinmesini engellemeye çalışmak için yakalamanın yığın çerçevesinin içinde kalmak için özyinelemeyi kullanabilir ya da std::exception_ptr öğelerini ve C++ 11'deki arkadaşlarınızı, istisnaları taşımak için kullanabilirsiniz.

+0

Teşekkürler. Ayrıca, bu [http://stackoverflow.com/questions/130117/throwing-exceptions-out-of-a-destructor] 'ı da ilginç buldum. – sp2danny

1

Bir arayana istisnayı iletmek için geçerli olan kullanım, onu yakalama bloğunda yeniden işlemektir. Yapmamanız için iyi nedenler varsayarsak, diğer tek doğru yolu std::exception_ptr kullanmaktır. Sadece bir std::exception* ile istisnanın yok edilmesi ve belleğinin yeniden atanması için önceden ayrılmış olması riski yüksektir.

standart C++ 2011 Tasarı (n4296) bir özel § 4 Fırlatma 15.1 mesajı: amacı herhangi bir vasıta ile bir istisna çıkış için kalan son aktif işleyici ya da sonra yok edilir durum, yeniden atma veya son dışında Özel durum nesnesine başvuran std :: exception_ptr türündeki nesne, daha sonra hangisi daha sonra yok edildi. Eski durumda, imha işleyicide istisna beyanında bildirilen nesnenin imha edilmesinden hemen sonra , eğer işleyiciden çıkarsa gerçekleşir. İkincisi durumunda, imha std :: exception_ptr'nin döndürücüsünden önce gerçekleşir. Uygulama daha sonra istisna nesnesi için belleği tahsis edebilir; bu tür herhangi bir ayrılma, belirtilmemiş bir numaralı yolla yolunda yapılır (benimkini vurgulayın)

İlgili konular