Menu
Coddy logo textTech

מצביעים חכמים ב-C++

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

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

כלול את הכותרת <memory> כדי להשתמש במצביעים חכמים.

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

#include <memory>

std::unique_ptr<Player> player = std::make_unique<Player>("Hero");
player->attack();  // השתמש כמו במצביע רגיל

// אי אפשר להעתיק, אבל אפשר להעביר בעלות
std::unique_ptr<Player> player2 = std::move(player);
// player הוא עכשיו nullptr

shared_ptr - בעלות משותפת. כמה מצביעים יכולים להיות הבעלים של אותו משאב. הזיכרון משתחרר כשהבעלים האחרון מושמד.

std::shared_ptr<Player> p1 = std::make_shared<Player>("Hero");
std::shared_ptr<Player> p2 = p1;  // שניהם מחזיקים בבעלות על המשאב

std::cout << p1.use_count();  // מדפיס 2

weak_ptr - מצביע תצפית שאינו בעלות על shared_ptr. שימושי לשבירת הפניות מעגליות.

std::shared_ptr<Player> shared = std::make_shared<Player>("Hero");
std::weak_ptr<Player> weak = shared;

if (auto locked = weak.lock()) {  // המר ל-shared_ptr
    locked->attack();
}

השתמשו כברירת מחדל ב־unique_ptr לבעלות יחידה. השתמשו ב־shared_ptr כשכמה אובייקטים צריכים לחלוק משאב. השתמשו ב־weak_ptr כדי לצפות בלי להאריך את משך החיים.

העדיפו make_unique ו־make_shared על פני new גולמי.

challenge icon

אתגר

קל

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

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

  • Document.h: הגדירו מחלקה בשם Document שמייצגת מסמך שניתן לשתף. היא צריכה לכלול:
    • מאפיין פרטי בשם title (מחרוזת)
    • בנאי שמקבל כותרת ומדפיס "Document created: <title>"
    • הורס שמדפיס "Document deleted: <title>"
    • מתודה בשם getTitle() שמחזירה את הכותרת
  • main.cpp: הדגימו את כל שלושת סוגי המצביעים החכמים על ידי קריאת כותרת של מסמך מהקלט, ואז:
    • צרו unique_ptr ל-Document עם הכותרת שהתקבלה בקלט
    • הדפיסו "Unique owner: <title>"
    • העבירו את הבעלות ל-unique_ptr אחר באמצעות std::move
    • הדפיסו "Ownership transferred"
    • צרו shared_ptr ל-Document חדש עם הכותרת "SharedDoc"
    • צרו shared_ptr שני שמצביע לאותו מסמך
    • הדפיסו "Shared owners: <count>" באמצעות use_count()
    • צרו weak_ptr מאחד המצביעים המשותפים
    • השתמשו ב-lock() כדי לגשת למסמך דרך המצביע החלש ולהדפיס "Weak access: <title>"

זכרו לכלול את <memory> עבור מצביעים חכמים. השתמשו ב-std::make_unique וב-std::make_shared כדי ליצור את המצביעים החכמים. הודעות ההרס יעזרו לכם לראות מתי כל מסמך מנוקה אוטומטית בסוף התוכנית.

כללו את קובץ הכותרת שלכם ב-main.cpp באמצעות #include "Document.h".

נסו בעצמכם

#include <iostream>
#include <memory>
#include <string>
#include "Document.h"

using namespace std;

int main() {
    string inputTitle;
    cin >> inputTitle;

    // TODO: צרו unique_ptr ל-Document עם inputTitle
    // באמצעות std::make_unique

    // TODO: הדפיסו "Unique owner: <title>"

    // TODO: העבירו את הבעלות ל-unique_ptr אחר באמצעות std::move

    // TODO: הדפיסו "Ownership transferred"

    // TODO: צרו shared_ptr ל-Document חדש עם הכותרת "SharedDoc"
    // באמצעות std::make_shared

    // TODO: צרו shared_ptr שני שמצביע לאותו מסמך

    // TODO: הדפיסו "Shared owners: <count>" באמצעות use_count()

    // TODO: צרו weak_ptr מאחד המצביעים המשותפים

    // TODO: השתמשו ב-lock() כדי לגשת למסמך דרך weak_ptr
    // והדפיסו "Weak access: <title>"

    return 0;
}
quiz iconבחנו את עצמכם

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

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

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