Menu
Coddy logo textTech

התמחות תבניות

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

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

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

// תבנית ראשית
template <typename T>
class Printer {
public:
    void print(T value) {
        std::cout << value << std::endl;
    }
};

// התמחות מלאה עבור const char*
template <>
class Printer<const char*> {
public:
    void print(const char* value) {
        std::cout << "String: " << value << std::endl;
    }
};

Printer<int> intPrinter;
intPrinter.print(42);           // פלט: 42

Printer<const char*> strPrinter;
strPrinter.print("hello");      // פלט: String: hello

אפשר גם ליצור התמחות לתבניות פונקציה:

template <typename T>
bool isEqual(T a, T b) {
    return a == b;
}

template <>
bool isEqual<const char*>(const char* a, const char* b) {
    return std::strcmp(a, b) == 0;
}

isEqual(5, 5);              // משתמש בגרסה הגנרית
isEqual("hi", "hi");        // משתמש בגרסה המתמחה

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

challenge icon

אתגר

קל

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

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

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

    תבנית Formatter הראשית צריכה לכלול:

    • מתודה format() שמקבלת ערך מסוג T ומדפיסה: Value: <value>

    צרו התמחות מלאה עבור bool שמדפיסה טקסט קריא לבני אדם במקום 1 או 0:

    • המתודה format() צריכה להדפיס: Boolean: true או Boolean: false

    צרו התמחות מלאה עבור const char* שמוסיפה מרכאות מסביב למחרוזות:

    • המתודה format() צריכה להדפיס: String: "<value>"

    צרו גם תבנית פונקציה בשם formatPair שמקבלת שני ערכים מאותו סוג ומדפיסה אותם יחד כך: Pair: [<first>, <second>]

    צרו התמחות של formatPair עבור const char* שעוטפת כל מחרוזת במרכאות: Pair: ["<first>", "<second>"]

  • main.cpp: קראו ארבעה קלטים (כל אחד בשורה נפרדת):
    1. מספר שלם
    2. מספר ממשי
    3. ערך בוליאני כמחרוזת (true או false)
    4. ערך מחרוזת

    הדגימו את מעצבי הפורמט שלכם על ידי יצירת אובייקטים מתאימים של Formatter וקריאה ל-format() עבור כל סוג:

    1. עצבו את המספר השלם באמצעות Formatter<int>
    2. עצבו את המספר הממשי באמצעות Formatter<double>
    3. עצבו את הערך הבוליאני באמצעות Formatter<bool> (תחילה המירו את קלט המחרוזת לערך בוליאני)
    4. עצבו את המחרוזת באמצעות Formatter<const char*>

    לאחר מכן הדגימו את ההתמחות של תבנית הפונקציה:

    1. קראו ל-formatPair עם שני מספרים שלמים: 10 ו-20
    2. קראו ל-formatPair עם שתי מחרוזות C: "hello" ו-"world"

לדוגמה, עם הקלטים 42, 3.14, true ו-Hello:

Value: 42
Value: 3.14
Boolean: true
String: "Hello"
Pair: [10, 20]
Pair: ["hello", "world"]

שימו לב כיצד התבנית הכללית מטפלת במספרים שלמים ובמספרים ממשיים באופן זהה, בעוד שהגרסאות המותאמות עבור bool ו-const char* מספקות עיצוב מותאם אישית. המהדר בוחר אוטומטית את ההתאמה הספציפית ביותר עבור כל סוג שבו משתמשים.

נסו בעצמכם

#include <iostream>
#include <string>
#include "Formatter.h"

using namespace std;

int main() {
    // קראו את ערכי הקלט
    int intVal;
    double doubleVal;
    string boolStr;
    string strVal;
    
    cin >> intVal;
    cin >> doubleVal;
    cin >> boolStr;
    cin >> strVal;
    
    // המירו את המחרוזת ל-bool
    bool boolVal = (boolStr == "true");
    
    // TODO: צרו Formatter<int> ועצבו את המספר השלם
    
    // TODO: צרו Formatter<double> ועצבו את המספר מסוג double
    
    // TODO: צרו Formatter<bool> ועצבו את הערך הבוליאני
    
    // TODO: צרו Formatter<const char*> ועצבו את המחרוזת
    // רמז: השתמשו ב-strVal.c_str() כדי לקבל const char*
    
    // TODO: קראו ל-formatPair עם שני מספרים שלמים: 10 ו-20
    
    // TODO: קראו ל-formatPair עם שתי מחרוזות C: "hello" ו-"world"
    
    return 0;
}
quiz iconבחנו את עצמכם

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

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

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