Menu
Coddy logo textTech

היררכיות חריגות מותאמות אישית

חלק מהיחידה תכנות מונחה עצמים במסלול ה-C++ של Coddy. שיעור 82 מתוך 104.

בעוד שהספרייה הסטנדרטית מספקת מחלקות חריגה שימושיות כמו std::runtime_error, יישומים מהעולם האמיתי מפיקים לעיתים קרובות תועלת מיצירת היררכיות חריגות מותאמות אישית. באמצעות הגדרת מחלקות חריגה משלך שיורשות מחריגות סטנדרטיות, תוכל ליצור סוגי שגיאות ייעודיים לתחום, הנושאים הקשר נוסף ומאפשרים טיפול מדויק יותר בשגיאות.

מחלקת חריגות מותאמת אישית יורשת בדרך כלל מ־std::exception או מאחת המחלקות הנגזרות ממנה, ודורסת את המתודה what():

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

היררכיה זו מאפשרת לבלוקי catch לטפל בחריגות ברמות שונות של ספציפיות:

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

המציין noexcept של what() חשוב — הוא מבטיח שהמתודה לא תזרוק חריגה, כנדרש בממשק מחלקת הבסיס. סדרו את בלוקי ה־catch מהספציפי ביותר לכללי ביותר, מכיוון ש־C++ משתמש במטפל הראשון שמתאים.

challenge icon

אתגר

קל

בואו נבנה מערכת לעיבוד קבצים עם היררכיית חריגות מותאמת אישית שמטפלת בסוגים שונים של שגיאות הקשורות לקבצים. תיצרו חריגות ייעודיות לתחום שיורשות ממחלקת חריגה בסיסית, וכך יתאפשר טיפול מדויק בשגיאות ברמות שונות של פירוט.

תארגנו את הקוד שלכם בשלושה קבצים:

  • FileExceptions.h: הגדירו את היררכיית החריגות המותאמת אישית שלכם עבור פעולות קבצים.

    צרו מחלקת בסיס בשם FileException שיורשת מ-std::exception. עליה לשמור הודעת שגיאה ולדרוס את המתודה what() עם המציין noexcept.

    לאחר מכן, צרו שתי מחלקות חריגה נגזרות:

    • FileNotFoundException: מקבלת שם קובץ ויוצרת הודעה: File not found: [filename]
    • PermissionDeniedException: מקבלת שם קובץ ויוצרת הודעה: Permission denied: [filename]

    כל מחלקה נגזרת צריכה לקרוא לבנאי של מחלקת האב שלה עם ההודעה המתאימה.

  • FileProcessor.h: הגדירו מחלקת FileProcessor שמדמה פעולות על קבצים וזורקת את החריגות המותאמות אישית שלכם.

    במחלקת FileProcessor צריכה להיות מתודה בשם openFile(const std::string& filename) שמדמה פתיחת קובץ:

    • אם שם הקובץ מכיל את missing, זרקו FileNotFoundException
    • אם שם הקובץ מכיל את locked, זרקו PermissionDeniedException
    • אחרת, החזירו את המחרוזת Successfully opened: [filename]
  • main.cpp: קראו שם קובץ יחיד מהקלט.

    צרו FileProcessor ונסו לפתוח את הקובץ. השתמשו בבלוק try-catch עם מטפלים המסודרים מהספציפי ביותר לכללי ביותר:

    1. תפסו FileNotFoundException והדפיסו: File Error: [message]
    2. תפסו PermissionDeniedException והדפיסו: Access Error: [message]
    3. תפסו FileException והדפיסו: General File Error: [message]

    אם לא נזרקת חריגה, הדפיסו את הודעת ההצלחה שמוחזרת על ידי openFile().

לדוגמה, עם הקלט report.txt:

Successfully opened: report.txt

עם הקלט missing_data.csv:

File Error: File not found: missing_data.csv

עם הקלט locked_config.ini:

Access Error: Permission denied: locked_config.ini

האתגר הזה מדגים כיצד היררכיות חריגות מותאמות אישית מאפשרות לכם לטפל בשגיאות ברמת הפירוט המתאימה: לתפוס חריגות ספציפיות כשנדרש טיפול מדויק, או לתפוס את חריגת הבסיס כשרוצים לטפל בכל שגיאות הקבצים באופן אחיד.

נסו בעצמכם

#include <iostream>
#include <string>
#include "FileExceptions.h"
#include "FileProcessor.h"

using namespace std;

int main() {
    string filename;
    cin >> filename;
    
    FileProcessor processor;
    
    // TODO: השתמשו בבלוק try-catch כדי לטפל בחריגות
    // סדרו את המטפלים מהספציפי ביותר לכללי ביותר:
    // 1. תפסו את FileNotFoundException - הדפיסו: "File Error: [message]"
    // 2. תפסו את PermissionDeniedException - הדפיסו: "Access Error: [message]"
    // 3. תפסו את FileException - הדפיסו: "General File Error: [message]"
    // אם לא התרחשה חריגה, הדפיסו את הודעת ההצלחה שמחזירה openFile()
    
    try {
        // TODO: קראו ל־processor.openFile() וטפלו בתוצאה
        
    }
    // TODO: הוסיפו בלוקי catch לפי הסדר, מהספציפי ביותר לכללי ביותר
    
    return 0;
}
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר C++ אונליין