Özel İstisna Hiyerarşileri
Coddy'nin C++ Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 82 / 104.
Standart kitaplık std::runtime_error gibi kullanışlı özel durum sınıfları sağlasa da gerçek dünya uygulamaları genellikle özel durum hiyerarşileri oluşturmaktan yarar görür. Standart özel durumlardan kalıtım alan kendi özel durum sınıflarınızı tanımlayarak ek bağlam taşıyan ve daha kesin hata işlemeye olanak tanıyan alana özgü hata türleri oluşturabilirsiniz.
Özel bir istisna sınıfı genellikle std::exception sınıfından veya onun türetilmiş sınıflarından miras alır ve what() yöntemini geçersiz kılar:
#include <exception>
#include <string>
class DatabaseException : public std::exception {
std::string message;
public:
DatabaseException(const std::string& msg) : message(msg) {}
const char* what() const noexcept override { return message.c_str(); }
};
class ConnectionException : public DatabaseException {
public:
ConnectionException(const std::string& host)
: DatabaseException("Failed to connect to: " + host) {}
};
class QueryException : public DatabaseException {
public:
QueryException(const std::string& query)
: DatabaseException("Invalid query: " + query) {}
};Bu hiyerarşi, catch bloklarının istisnaları farklı özgüllük düzeylerinde işlemesine olanak tanır:
try {
// veritabanı işlemleri...
throw ConnectionException("localhost");
} catch (const ConnectionException& e) {
std::cout << "Connection issue: " << e.what() << "\n";
} catch (const DatabaseException& e) {
std::cout << "Database error: " << e.what() << "\n";
} catch (const std::exception& e) {
std::cout << "General error: " << e.what() << "\n";
}noexcept belirtecinin what() üzerinde kullanılması önemlidir — yöntemin hata fırlatmayacağını garanti eder; bu, base sınıfı arayüzü tarafından gereklidir. C++ ilk eşleşen işleyiciyi kullandığından, catch bloklarını en özeldenden en genele doğru sıralayın.
Görev
KolayFarklı dosya kaynaklı hata türlerini işleyen özel bir istisna hiyerarşisine sahip bir dosya işleme sistemi oluşturalım. Bir temel istisna sınıfından kalıtım alan, alana özgü istisnalar oluşturacak ve farklı özgüllük düzeylerinde hassas hata işleme olanağı sağlayacaksınız.
Kodunuzu üç dosya arasında düzenleyeceksiniz:
FileExceptions.h: Dosya işlemleri için özel istisna hiyerarşinizi tanımlayın.FileExceptionsınıfından kalıtım alan bir temelstd::exceptionsınıfı oluşturun. Bu sınıf bir hata mesajı saklamalı vewhat()belirteciylenoexceptyöntemini geçersiz kılmalıdır.Ardından türetilmiş iki istisna sınıfı oluşturun:
FileNotFoundException: bir dosya adı alır ve şu mesajı oluşturur:File not found: [filename]PermissionDeniedException: bir dosya adı alır ve şu mesajı oluşturur:Permission denied: [filename]
Her türetilmiş sınıf, uygun mesajla üst sınıf oluşturucusunu çağırmalıdır.
FileProcessor.h: Dosya işlemlerini simüle eden ve özel istisnalarınızı fırlatan birFileProcessorsınıfı tanımlayın.FileProcessorsınıfınızda, bir dosyayı açmayı simüle edenopenFile(const std::string& filename)yöntemi bulunmalıdır:- Dosya adı
missingiçeriyorsa birFileNotFoundExceptionfırlatın - Dosya adı
lockediçeriyorsa birPermissionDeniedExceptionfırlatın - Aksi takdirde
Successfully opened: [filename]dizesini döndürün
- Dosya adı
main.cpp: Girdiden tek bir dosya adı okuyun.Bir
FileProcessoroluşturun ve dosyayı açmayı deneyin. İşleyicileri en özgü olandan en genele doğru sıralanmış bir try-catch bloğu kullanın:FileNotFoundExceptionyakalayın ve şunu yazdırın:File Error: [message]PermissionDeniedExceptionyakalayın ve şunu yazdırın:Access Error: [message]FileExceptionyakalayın ve şunu yazdırın:General File Error: [message]
Hiçbir istisna fırlatılmazsa
openFile()tarafından döndürülen başarı mesajını yazdırın.
Örneğin, report.txt girdisiyle:
Successfully opened: report.txtmissing_data.csv girdisiyle:
File Error: File not found: missing_data.csvlocked_config.ini girdisiyle:
Access Error: Permission denied: locked_config.iniBu görev, özel istisna hiyerarşilerinin hataları uygun ayrıntı düzeyinde ele almanıza nasıl olanak sağladığını gösterir: hassas işlemeye ihtiyaç duyduğunuzda belirli istisnaları yakalayabilir veya tüm dosya hatalarını tek tip biçimde ele almak istediğinizde temel istisnayı yakalayabilirsiniz.
Kendin dene
#include <iostream>
#include <string>
#include "FileExceptions.h"
#include "FileProcessor.h"
using namespace std;
int main() {
string filename;
cin >> filename;
FileProcessor processor;
// TODO: İstisnaları ele almak için bir try-catch bloğu kullan
// İşleyicileri en spesifikten en genele doğru sırala:
// 1. FileNotFoundException yakala - yazdır: "File Error: [message]"
// 2. PermissionDeniedException yakala - yazdır: "Access Error: [message]"
// 3. FileException yakala - yazdır: "General File Error: [message]"
// İstisna yoksa, openFile()'dan gelen başarı mesajını yazdır
try {
// TODO: processor.openFile() çağır ve sonucu işle
}
// TODO: catch bloklarını en spesifikten en genele doğru sırayla ekle
return 0;
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1OOP Temelleri
Harici DosyalarC++ Build ve DerlemeBaşlık Dosyaları ve Kaynak DosyalarıAd Alanları ve KapsamC++'ta OOP'ye GirişSınıflar ve Nesneler'this' İşaretçisiMetotlar (Üye Fonksiyonlar)Öznitelikler (Veri Üyeleri)Ctor ve Dtor TemelleriÖzet - Basit Hesap Makinesi4Sınıf Özellikleri
Örnek ve Statik ÜyelerGetter ve Setter MetotlarıConst Üye FonksiyonlarMutable Anahtar KelimesiStatik Metotlar ve DeğişkenlerFriend Fonksiyonlar ve SınıflarÖzet - Banka Hesabı Yöneticisi7Kalıtım
Temel KalıtımKalıtım Erişim SeviyeleriCtor ve Dtor Çağrılma SırasıMetot Geçersiz KılmaSanal Fonksiyonlar ve VTableÇoklu KalıtımSanal KalıtımÖzet - Çalışan Hiyerarşisi10STL Genel Bakış
STL Genel Bakış ve FelsefesiSTL KonteynerleriİteratörlerSTL AlgoritmalarıFunctor'lar ve Lambda İfadeleriÖzet - Kelime Frekansı13Tasarım Kalıpları 1. Bölüm
Tasarım Kalıplarına GirişSingleton KalıbıFactory ve Abstract FactoryBuilder KalıbıObserver KalıbıStrategy Kalıbı2Bellek Yönetimi
Stack ve Heap Bellekİşaretçiler ve ReferanslarDinamik Bellek (new/delete)C++'ta Akıllı İşaretçilerC++'ta RAIIÖzet - Dinamik Dizi Yöneticisi5Kapsülleme
C++'da Erişim BelirleyicilerDerinlemesine Erişim BelirleyicilerBilgi GizlemeStruct vs Classİç İçe ve Dahili SınıflarÖzet - Öğrenci Kayıt Sistemi8Çok Biçimlilik
Derleme ve Çalışma Zamanı Çok BiçimliliğiFonksiyon Aşırı YüklemeSanal Fonksiyonlara Yeniden BakışSaf Sanal FonksiyonlarSoyut SınıflarC++'ta Arayüz TasarımıDynamic Casting ve RTTIÖzet - Şekil Hesaplayıcı11İleri Düzey OOP Kavramları
Kompozisyon ve Kalıtım KarşılaştırmasıCRTP ile Mixin YapılarıPimpl İdiyomuTür Silme (Type Erasure)Enum Sınıfları ve Güçlü TiplendirmeOOP'de İstisna YönetimiÖzel İstisna Hiyerarşileri3Yapıcılar ve Yıkıcılar
Varsayılan YapıcıParametreli YapıcıKopya YapıcıTaşıma YapıcısıYapıcı İlklendirme ListeleriTemsilci YapıcılarYıkıcılara Derinlemesine BakışÜç / Beş / Sıfır KuralıÖzet - String Sınıfı6Operatör Aşırı Yükleme
Operatör Aşırı Yüklemeye GirişAritmetik Operatör Aşırı YüklemeKarşılaştırma Operatörü Aşırı YüklemeStream OperatörleriAtama Operatörü Aşırı Yükleme[] ve () Operatör Aşırı YüklemeTip Dönüşüm OperatörleriÖzet - Matris Sınıfı9Şablonlar
Fonksiyon ŞablonlarıSınıf ŞablonlarıŞablon ÖzelleştirmeVariadic ŞablonlarSFINAE ve Type Traits TemelleriÖzet - Generic KonteynerKendi başına pratik yap: Online C++ derleyicisi