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 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.

challenge icon

Görev

Kolay

Farklı 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.

    FileException sınıfından kalıtım alan bir temel std::exception sınıfı oluşturun. Bu sınıf bir hata mesajı saklamalı ve what() belirteciyle noexcept yö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 bir FileProcessor sınıfı tanımlayın.

    FileProcessor sınıfınızda, bir dosyayı açmayı simüle eden openFile(const std::string& filename) yöntemi bulunmalıdır:

    • Dosya adı missing içeriyorsa bir FileNotFoundException fırlatın
    • Dosya adı locked içeriyorsa bir PermissionDeniedException fırlatın
    • Aksi takdirde Successfully opened: [filename] dizesini döndürün
  • main.cpp: Girdiden tek bir dosya adı okuyun.

    Bir FileProcessor oluşturun ve dosyayı açmayı deneyin. İşleyicileri en özgü olandan en genele doğru sıralanmış bir try-catch bloğu kullanın:

    1. FileNotFoundException yakalayın ve şunu yazdırın: File Error: [message]
    2. PermissionDeniedException yakalayın ve şunu yazdırın: Access Error: [message]
    3. FileException yakalayı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.txt

missing_data.csv girdisiyle:

File Error: File not found: missing_data.csv

locked_config.ini girdisiyle:

Access Error: Permission denied: locked_config.ini

Bu 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;
}
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

Kendi başına pratik yap: Online C++ derleyicisi