דילוג לתוכן המרכזי
מודול 7 · שיעור 1 מתוך 215/18 בקורס~12 min
שיעורי מודול (1/2)

std::unique_ptr ו-std::shared_ptr

ב-C++ הקלאסי, ניהול זיכרון ידני באמצעות האופרטורים new וdelete הוא מקור נפוץ לבאגים כגון דליפות זיכרון (משאבים מעולם לא שוחררו) או מצביעים משתלשלים (מצביעים המצביעים על זיכרון שהוקצה).

C++ המודרני מציג את Smart Pointers, המוגדרים בכותרת <memory>. הם מנהלים אוטומטית את מחזור החיים של זיכרון שהוקצה בערימה באמצעות RAII (Resource Acquisition Is Initialization), ומבטלים את הקצאת המשאב כאשר המצביע החכם יוצא מהתחום.

std::unique_ptr

std::unique_ptr מיישם את הרעיון של בעלות בלעדית על משאב. לא ניתן להעתיק אותו, רק להעביר אותו (דרך std::move).

C++
#include <memory>

// Recommended creation using std::make_unique (C++14)
std::unique_ptr<int> p1 = std::make_unique<int>(42);

// Accessing the resource like a normal pointer
std::cout << *p1 << std::endl;

// std::unique_ptr<int> p2 = p1; // COMPILER ERROR: copy not allowed!
std::unique_ptr<int> p2 = std::move(p1); // Allowed: p1 transfers ownership to p2

std::shared_ptr

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

C++
#include <memory>

std::shared_ptr<int> s1 = std::make_shared<int>(100);
std::shared_ptr<int> s2 = s1; // Allowed: increments the reference count

std::cout << s1.use_count() << std::endl; // Prints 2 (s1 and s2 share the resource)

נסה זאת בעצמך

פעילות גופנית#cpp.m7.l1.e1
ניסיונות: 0טוען...

הכריז על std::unique_ptr<int> בשם ptr, אתחול אותו עם std::make_unique המחזיק את הערך 42. הדפס את הערך המיוחל של ptr באמצעות std::cout.

טוען עורך...
הצג רמז

השתמש ב-`std::unique_ptr<int> ptr = std::make_unique<int>(42);` ולאחר מכן שלח `*ptr` לזרם הפלט.

הפתרון זמין לאחר 3 ניסיונות

פעילות גופנית#cpp.m7.l1.e2
ניסיונות: 0טוען...

הצג std::shared_ptr<int> בשם ptr1 עם הערך 100 באמצעות std::make_shared. צור עותק בשם ptr2, והדפיס את הערך המוחזר על ידי ptr1.use_count() באמצעות std::cout.

טוען עורך...
הצג רמז

ההעתקה מתבצעת באמצעות מטלה סטנדרטית: `ptr2 = ptr1;`. הדפסת `ptr1.use_count()` אמורה להציג 2.

הפתרון זמין לאחר 3 ניסיונות