Menu
Coddy logo textTech

Ö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 kütüphane std::runtime_error gibi kullanışlı istisna sınıfları sağlasa da, gerçek dünya uygulamaları genellikle özel istisna hiyerarşileri oluşturmaktan fayda sağlar. Standart istisnalardan miras alan kendi istisna sınıflarınızı tanımlayarak, ek bağlam taşıyan ve daha kesin hata yönetimi sağlayan 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 birinden miras alır ve what() metodunu geçersiz kılar (override eder):

#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ünlük seviyelerinde ele almasına 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";
}

what() üzerindeki noexcept belirleyicisi önemlidir - metodun hata fırlatmayacağını garanti eder, ki bu temel sınıf arayüzü tarafından gereklidir. C++ ilk eşleşen işleyiciyi kullandığından, catch bloklarınızı en özelden en genele doğru sıralayın.

challenge icon

Görev

Kolay

Farklı türdeki dosyayla ilgili hataları işleyen özel bir istisna hiyerarşisine sahip bir dosya işleme sistemi oluşturalım. Farklı özgünlük seviyelerinde hassas hata işlemeye olanak tanıyan, temel bir istisna sınıfından miras alan alana özgü istisnalar oluşturacaksınız.

Kodunuzu üç dosya halinde düzenleyeceksiniz:

  • FileExceptions.h: Dosya işlemleri için özel istisna hiyerarşinizi tanımlayın.

    std::exception sınıfından miras alan temel bir FileException sınıfı oluşturun. Bu sınıf bir hata mesajı saklamalı ve what() metodunu noexcept belirleyicisi ile geçersiz kılmalıdır (override).

    Ardından iki türetilmiş istisna sınıfı oluşturun:

    • FileNotFoundException — bir dosya adı alır ve şu mesajı oluşturur: "File not found: " + dosya adı
    • PermissionDeniedException — bir dosya adı alır ve şu mesajı oluşturur: "Permission denied: " + dosya adı

    Her türetilmiş sınıf, uygun mesajla üst sınıf kurucusunu çağırmalıdır.

  • FileProcessor.h: Dosya işlemlerini simüle eden ve özel istisnalarınızı fırlatan bir FileProcessor sınıfı tanımlayın.

    FileProcessor sınıfınız, bir dosyayı açmayı simüle eden bir openFile(const std::string& filename) metoduna sahip olmalıdır:

    • Eğer dosya adı "missing" içeriyorsa, bir FileNotFoundException fırlatın
    • Eğer dosya adı "locked" içeriyorsa, bir PermissionDeniedException fırlatın
    • Aksi takdirde, "Successfully opened: " + dosya adı dizesini döndürün
  • main.cpp: Girişten tek bir dosya adı okuyun.

    Bir FileProcessor oluşturun ve dosyayı açmaya çalışın. En özelden en genele doğru sıralanmış işleyicilere sahip bir try-catch bloğu kullanın:

    1. FileNotFoundException yakalayın ve şunu yazdırın: "File Error: " + hata mesajı
    2. PermissionDeniedException yakalayın ve şunu yazdırın: "Access Error: " + hata mesajı
    3. FileException yakalayın ve şunu yazdırın: "General File Error: " + hata mesajı

    Eğer hiçbir istisna fırlatılmazsa, openFile() tarafından döndürülen başarı mesajını yazdırın.

Örneğin, report.txt girişi ile:

Successfully opened: report.txt

missing_data.csv girişi ile:

File Error: File not found: missing_data.csv

locked_config.ini girişi ile:

Access Error: Permission denied: locked_config.ini

Bu zorluk, özel istisna hiyerarşilerinin hataları uygun ayrıntı düzeyinde işlemenize nasıl olanak tanıdığını gösterir; hassas işlemeye ihtiyaç duyduğunuzda belirli istisnaları yakalayabilir veya tüm dosya hatalarını tek tipte işlemek istediğinizde temel istisnayı yakalayabilirsiniz.

Kopya kağıdı

Özel istisna sınıfları std::exception veya onun türetilmiş sınıflarından miras alır ve what() metodunu geçersiz kılar (override eder):

#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(); }
};

Özel temel istisnalardan miras alarak istisna hiyerarşileri oluşturun:

class ConnectionException : public DatabaseException {
public:
    ConnectionException(const std::string& host) 
        : DatabaseException("Failed to connect to: " + host) {}
};

Catch bloklarını en özelden en genele doğru sıralayarak istisnaları farklı özgünlük seviyelerinde ele alın:

try {
    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";
}

what() üzerindeki noexcept belirleyicisi, metodun istisna fırlatmayacağını garanti eder; bu, temel sınıf arayüzü tarafından zorunludur.

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ı işlemek için bir try-catch bloğu kullanın
    // İşleyicileri en özelden en genele doğru sıralayın:
    // 1. FileNotFoundException yakalayın - yazdırın: "File Error: [message]"
    // 2. PermissionDeniedException yakalayın - yazdırın: "Access Error: [message]"
    // 3. FileException yakalayın - yazdırın: "General File Error: [message]"
    // Eğer istisna yoksa, openFile() fonksiyonundan gelen başarı mesajını yazdırın
    
    try {
        // TODO: processor.openFile() fonksiyonunu çağırın ve sonucu işleyin
        
    }
    // TODO: Catch bloklarını en özelden en genele doğru sırayla ekleyin
    
    return 0;
}
quiz iconKendini test et

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