ProgramlamaC++ sistem programcısı

C++'da istisna (exceptions) çalışma mekanizmalarından bahsedin. Hatalar nasıl düzgün bir şekilde işlenir ve noexcept neden gereklidir?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Konu geçmişi:

C++'da istisna işleme mekaniği, hata kodlarının aksine daha güvenilir ve yapılandırılmış bir hata yönetimi sağlamak için tanıtıldı. Yıllar geçtikçe, sözdizimi genişledi ve istisna fırlatma işlemlerini kontrol etmek için noexcept türünde belirleyiciler eklendi.

Sorun:

İstisnalarla yanlış çalışma genellikle bellek sızıntılarına, belirsiz davranışlara veya uygulamaların çökmesine neden olur. Yapıcılardan, yıkıcılardan veya kaynaklarla çalışırken istisna fırlatmayı dikkate almazsanız, programın durumu ile ilgili ciddi bir sorun ortaya çıkar.

Çözüm:

Temel sözdizimi — try-catch kullanımıdır. İstisnalar herhangi bir türde olabilir, ancak kullanıcı tanımlı istisnaların std::exception'dan türemesi önerilir. noexcept anahtar kelimesi (C++11+) bir fonksiyonun istisna fırlatmaması gerektiğini belirtir; noexcept fonksiyonundan istisna fırlatılması std::terminate() çağrısını tetikler.

Kod örneği:

#include <iostream> #include <stdexcept> void func() noexcept(false) { throw std::runtime_error("Hata!"); } int main() { try { func(); } catch(const std::exception& ex) { std::cout << ex.what(); } }

Anahtar özellikler:

  • İstisnalar otomatik unwind (yığın açılımı) sağlar.
  • noexcept, fonksiyonun kesinlikle istisna fırlatmadığını garanti ederse derleyicinin optimizasyon yapmasına olanak tanır.
  • Sadece std::exception ve onun türevleri what() metodunun varlığını garanti eder.

Soru tuzakları.

Yıkıcıda istisna fırlatmak kabul edilebilir mi?

Hayır, yıkıcıdan istisna fırlatmak yığın açılımı sırasında std::terminate() ile sonuçlanır. Yıkıcılardaki istisnalar, yıkıcının kendisi içinde yakalanmalıdır.

noexcept fonksiyonundan istisna fırlatılırsa ne olur?

std::terminate çağrılır, program aniden sona erer. noexcept — katı bir sözleşmedir.

Değer üzerinden istisna yakalamak mümkün mü? Bu ne kadar tehlikeli?

Değer üzerinden yakalamak mümkündür, ancak nesne kopyalanır (object slicing). const & kullanılması önerilir.

Kod örneği:

try { throw std::out_of_range("hata"); } catch (const std::exception& e) { /* ... */ }

Tipik hatalar ve anti-patentler

  • Yıkıcılarda throw kullanmak
  • İstisnaları yakalayıp loglama yapmadan catch(...) ile yutmak
  • Mümkün olan yerlerde noexcept belirtmemek

Hayattan bir örnek

Olumsuz durum

Kod, kaynakların yıkıcılarında istisnalar fırlatıyordu; aniden sona erme durumunda yığın yanlış bir şekilde açılıyordu, kaynaklar sızıyordu.

Artıları:

  • Hataların hızlı bir şekilde tespit edilmesi mümkündür.

Eksileri:

  • Programlar sık sık terminate hatası veriyordu.

Olumlu durum

Kritik yöntemler noexcept ile işaretlendi, yıkıcılar tüm istisnaları içinde işledi. Referans üzerinden yakalamalar yapıldı, tüm hatalar kaydedildi.

Artıları:

  • Güvenilirlik, sızıntı yokluğu
  • Son derece öngörülebilir davranış

Eksileri:

  • Geliştiricinin doğru, "temiz" kod yazma konusunda daha katı olması gerekmektedir.