42
ססססס סס'12 ( תתתתת תתתתתתת תתתתתתתתתSTL ) תתתתת תתתתתתתתתת תתתתתת תתתתתתת תתתתת

תרגול מס' 12

  • Upload
    harken

  • View
    94

  • Download
    1

Embed Size (px)

DESCRIPTION

תרגול מס' 12. ספרית התבניות הסטנדרטית ( STL ) כתיבת אלגוריתמים גנריים מצביעים חכמים. ספרית התבניות הסטנדרטית ( STL ). vector list iterator. ספרית התבניות הסטנדרטית. קיימת בכל מימוש של ++ C מכילה אוספים (Containers) ואלגוריתמים משתמשת בתבניות (templates) : אוספי הנתונים גנריים - PowerPoint PPT Presentation

Citation preview

Page 1: תרגול מס' 12

12תרגול מס' ( ספרית התבניות הסטנדרטיתSTL)כתיבת אלגוריתמים גנרייםמצביעים חכמים

Page 2: תרגול מס' 12

2מבוא לתכנות מערכות - 234122

ספרית התבניות (STLהסטנדרטית )

vectorlistiterator

Page 3: תרגול מס' 12

3מבוא לתכנות מערכות - 234122

ספרית התבניות הסטנדרטית

++ קיימת בכל מימוש שלC

מכילה אוספים(Containers)ואלגוריתמים

משתמשת בתבניות(templates):אוספי הנתונים גנריים–

האלגוריתמים המסופקים גנריים–

מאפשרת הרחבה ע"י המשתמש–

שומרת על יעילות הקוד–

Page 4: תרגול מס' 12

4מבוא לתכנות מערכות - 234122

std::vector – נכיר תחילה את האוסף הפשוט ביותר בספריהvector.

מערך סדור של איברים–

מאפשר גישה לכל איבר באוסף–

מאפשר הוספת והסרת איברים–

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

דוגמאות הקוד מתרכזות בשימוש בסיסי ופשוט.

Page 5: תרגול מס' 12

5מבוא לתכנות מערכות - 234122

vectorמתודות נבחרות של ][ גישה בעזרת אופרטור

אינה בטוחה אינה מוודאת את חוקיות –

האינדקס

גישה בעזרת at זורקת )( out_of_rangeחריגה מסוג

עבור אינדקס לא חוקי

template<typename T>class vector {

vector();vector(const vector& c);vector(size_t num, const T&

val = T());~vector();

 T& operator[](size_t index);const T& operator[](size_t

index) const;vector operator=(const vector&

v); 

T& at(size_t loc);const T& at(size_t loc) const;

 void pop_back();void push_back(const T& val);

size_t size() const;};

 

Page 6: תרגול מס' 12

6מבוא לתכנות מערכות - 234122

vectorדוגמאות לשימוש ב-int main() {

vector<int> v1; // empty vectorvector<int> v2(20, 8); // 20 integers, all

of value 8 

for(size_t i = 0; i < v2.size(); ++i) {cout << v2[i]; // Unsafe access by

index}for(int i = 0; i < 10; ++i) {

v1.push_back(i);// Inserts items at the end of the

vector}while(v1.size() > 0) {

v1.pop_back();}const vector<int> copy(v1); //Safely

copies a vector 

return 0;}

Page 7: תרגול מס' 12

7מבוא לתכנות מערכות - 234122

יתרונות

ניהול זיכרון ע"י המחלקהלא צריך לזכור לשחרר ידנית את המערך–

ניתן לשנות את גודל המערך בקלות–

ניתן ליצור העתקים ולבצע השמות בקלות–

גישה בטוחה)(atרק כאשר משתמשים ב-–

?][ כיצד נוכל ליצור וקטור בטוח עבור

template<typename T>class SafeVector : public vector<T> { 

SafeVector() : vector<T>() {}

SafeVector(int s) : vector<T>(s) {} 

T& operator[](int i) {return at(i);

}const T& operator[](int i)

const {return at(i);

}};

 

Page 8: תרגול מס' 12

8מבוא לתכנות מערכות - 234122

std::listדומה לוקטור, אך המימוש הוא ברשימה מקושרת

שימוש ברשימה מקושרת מאפשר הוספת איברים מהירה יותר, אך אינו –מאפשר גישה מהירה לאמצע האוסף

ההבדל העיקרי ביןlist-ל vector הוא במימוש, לכן לשני האוספים מנשק דומה

השימוש במנשק דומה מאפשר למשתמש להחליף בקלות את סוג האוסףבשימוש גם בשלבים מאוחרים

, ורק vectorכאמור, סיבוכיות היא שיקול משני בד"כ ולכן ניתן להשתמש ב-–בהמשך כשיש צורך ברשימה מקושרת ניתן לעבור לשימוש בה

Page 9: תרגול מס' 12

9מבוא לתכנות מערכות - 234122

listמתודות נבחרות של נוספו מתודות להסרת

והוספת איברים גם בראש הרשימה

מתודות לגישה לאיברבאמצע הרשימה נעלמו

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

template<typename T>class list {

list();list(const list& c);list(size_t num, const T&

val = T());~list();

 list operator=(const list&

v); 

void pop_back();void push_back(const T&

val);void pop_front();void push_front(const T&

val); 

size_t size() const;};

Page 10: תרגול מס' 12

10מבוא לתכנות מערכות - 234122

Iteratorsאיטרטורים - איטרטורעל מנת לאפשר מעבר סדור על איברי אוסף נשתמש ב

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

: החזרת האיבר המוצבע ע"י האיטרטורקריאה–

: בדיקה האם שני איטרטורים מצביעים לאותו איברהשוואה–

,איטרטור אינו מחלקה(conceptאלא מושג )

למשל מצביע הוא איטרטור–Cעבור מערך של

int* array = new int[n];//...int* i = array;cout << *i << endl; // Reading the iteratori++; // Advancing the iterator by 1if (i == array+n) { // Comparing to iterators

cout << "End of array!" << endl;}

Page 11: תרגול מס' 12

11מבוא לתכנות מערכות - 234122

STLאיטרטורים וה--כל האוספים המאפשרים מעבר על איבריהם בSTL מספקים iterator

בעזרתו ניתן לעבור על איבריהם

המתודהbegin מחזירה )(iteratorמתאים לתחילת האוסף המתודהend מחזירה )(iterator מתאים לאיבר "דמה" אחרי האיבר

האחרון

!למשתמש לא אכפת כיצד ממומש האיטרטור

Page 12: תרגול מס' 12

12מבוא לתכנות מערכות - 234122

דוגמאות לשימוש באיטרטורים

הדפסת איבריvector:

הדפסת איבריlist:

-ניתן לגשת בצורה דומה לכל אוסף בSTLהמאפשר גישה לאיבריו -הטיפוס עבור הiteratorהמתאים מוגדר בתוך כל אוסף בעזרת השם

container<int>::iterator

for(vector<int>::iterator i = v.begin();i != v.end(); ++i) {

cout << *i << endl;}

for(list<int>::iterator i = l.begin();i != l.end(); ++i) {

cout << *i << endl;}

Page 13: תרגול מס' 12

13מבוא לתכנות מערכות - 234122

const_iterator בנוסף כל אוסף מגדיר גם טיפוסconst_iterator

כך ניתן להגן על האוסף–מפני שינויים כאשר הוא

constמוגדר כ-

טיפוס האיטרטור המוחזרנקבע בעזרת העמסה על

המתודות המתאימות

const vector<int> v;vector<int>::const_iterator i = v.begin();*i = 7; // error! *i is const int&

vector<int> v;vector<int>::iterator i = v.begin();*i = 7; // O.K.! *i is int&

Page 14: תרגול מס' 12

14מבוא לתכנות מערכות - 234122

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

:מחיקת האיבר החמישי בוקטור

לביטול התוקף של איטרטור שינויים באוסף עלולים לגרום(invalidation)אינה מוגדרתגישה לאיטרטור שאינו בתוקף –

עלולה לגרום לכל האיטרטורים לצאת מתוקףvector::insertלמשל –

שכל שינוי של אוסף מוציא מתוקף את כל ההנחה המחמירה מומלץ להניח את –האיטרטורים שלו

אם הנחה זו מחמירה מדי ניתן למצוא מידע מדויק בתיעוד האוסף•

list<double>::iterator i = myList.begin();while (i != myList.end() && num < *i) {

++i;}myList.insert(i, num); // Insert num before i

myVector.erase(v.begin() + 4);

Page 15: תרגול מס' 12

15מבוא לתכנות מערכות - 234122

סוגי איטרטורים

אוספים שונים מחזירים איטרטורים שונים המאפשר קידום האיטרטור עם אופרטורbidirectional iterator למשל, יש listל-–

++ והחזרתו לאחור עם אופרטור--

המאפשר גם חיבור מספרים לאיטרטור random access iterator יש vectorל –וחישוב הפרש בין שני איטרטורים )בדומה למצביע(

-לvector-ו listמס' רב של מתודות ואופרטורים נוספים STLכמעט כל פעולה שעולה בדעתכם לבצע כבר ממומשת ב-–ניתן פשוט לחפש באינטרנט:–

/http://www.cppreference.comלמשל •

-יש עוד אוספים בSTL ומבני נתונים נוספים שלא נלמדו בקורסset, stackלמשל –

Page 16: תרגול מס' 12

16מבוא לתכנות מערכות - 234122

ספרית התבניות הסטנדרטית - סיכום

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

צורה לאוספים שונים

Page 17: תרגול מס' 12

17מבוא לתכנות מערכות - 234122

כתיבת אלגוריתמים גנריים

איטרטוריםאלגוריתמיםfunction objects

Page 18: תרגול מס' 12

18מבוא לתכנות מערכות - 234122

maxאלגוריתם ברצוננו לכתוב פונקציה אשר

מוצאת את האיבר המקסימלי

כיצד נוכל לאפשר לפונקציהלעבוד על כל אוסף אפשרי?

:דוגמאות לשימושמציאת הערך הגדול ביותר בוקטור–

מחיקת האיבר הגדול ביותר ברשימה–

template<typename Iterator>Iterator max(Iterator start, Iterator end) {

if (start == end) {return end;

}Iterator maximum = start;for(Iterator i = ++start; i !=

end; ++i) {if (*i > *maximum) {

maximum = i;}

}return maximum;

} int m = *max(myVector.begin(), myVector.end());

myList.erase(max(myList.begin(), myList.end()));

Page 19: תרגול מס' 12

19מבוא לתכנות מערכות - 234122

יתרונות

:אלגוריתם יחיד מתאים לכל המקריםאוספים שונים–

רק חלקים מהאוסף ניתנים למעבר–

קל להתאים קוד קיים שיעבוד עם האלגוריתם–

:Cלמשל שימוש באלגוריתם עבור מערך רגיל של •

int* myArray = new int[size];//...int m = *max(myArray, myArray+size);

Page 20: תרגול מס' 12

20מבוא לתכנות מערכות - 234122

algorithm-מלבד מבני הנתונים הSTL מכיל גם אוסף אלגוריתמים מועילים הניתנים

להפעלה על כל מבנה נתונים מתאיםחלקם פשוטים:–

וחלקם פחות:–

template<typename Iterator>void random_shuffle(Iterator start, Iterator end);

template<typename Iterator>void sort(Iterator start, Iterator end);

template<typename Iterator, typename T>Iterator find(Iterator start, Iterator end, const T& val);

Page 21: תרגול מס' 12

21מבוא לתכנות מערכות - 234122

Function Objectsבמקום לשלוח מצביעים לפונקציות ב STL-משתמשים ב-“function

objects”Function object אופרטור אופרטור )( הוא כל עצם המעמיס את(

ההפעלה(

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

int ומחזירה bool

class LessThanZero {public:

bool operator()(int m) const {return m < 0;

}};

void f() {LessThanZero isNegative;cout << isNegative(-4) <<

endl; // truecout << isNegative(6) << endl;

// false}

Page 22: תרגול מס' 12

22מבוא לתכנות מערכות - 234122

Function Objects אופרטור ההפעלה ניתן להגדרה עם מספר

כלשהו של פרמטרים

בניגוד למצביעים לפונקציות, ניתן לזכור ולכן ניתן להשתמש Function Objectמצב ב-

באותה מחלקה למס' פונקציות השונות רק בפרמטר כלשהו

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

void h() {LessThan isLess(5);LessThan isLess2(8);cout << isLess(4) << endl; //

truecout << isLess(6) << endl; //

falsecout << isLess2(6) << endl; //

true}

class LessThan {int n;

public:LessThan(int n) : n(n)

{}bool operator()(int m)

const {return m < n;

}};

void g() {SumOf isSum;cout << isSum(2,3,5) << endl;

// truecout << isSum(1,2,5) << endl;

// false}

class SumOf {public:

bool operator()(int a, int b, int s) {

return a + b == s;}

};

Page 23: תרגול מס' 12

23מבוא לתכנות מערכות - 234122

Function Objectsדוגמה -

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

template<typename Iterator, typename Predicate>Iterator find_if(Iterator first, Iterator last, Predicate pred) {

for (; first != last; first++)if (pred(*first))

break;return first;

}

vector<int> v;vector<int>::iterator i = find_if(v.begin(),v.end(),LessThan(2));vector<int>::iterator j = find_if(v.begin(),v.end(),LessThan(7));

Page 24: תרגול מס' 12

24מבוא לתכנות מערכות - 234122

דוגמה נוספת

ניצור קריטריון מיון חדש למספרים שלמים כך שנוכל למיין לפי ערך:mהמספר מודולו

בכדי למיין פשוט נקרא לאלגוריתםהמיון עם פרמטר נוסף:

class LessThanModulo {int m;

public:LessThanModulo(int

m) : m(m) {}bool operator()(int a,

int b) {return a%m < b

%m;}

};sort(v.begin(), v.end(), LessThanModulo(5)); 

Page 25: תרגול מס' 12

25מבוא לתכנות מערכות - 234122

הוספת תמיכה באיטרטורים ניזכר במחלקת String 9 שהגדרנו בתרגול ,

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

.עלינו להוסיף תמיכה באיטרטורים במחלקה

במקרה שלString נוכל פשוט להשתמש ,charבמצביע ל-

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

charמשתמשים במצביע ל-

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

חדשה עבור איטרטור

class String {int length;char* value;

public://...typedef char* iterator;typedef const char*

const_iterator;

iterator begin() {return value;

}const_iterator begin()

const {return value;

}iterator end() {

return value+length;

}const_iterator end() const

{return

value+length;}//...

};

Page 26: תרגול מס' 12

26מבוא לתכנות מערכות - 234122

שימוש

האלגוריתםtransform מפעיל פונקציה על תחום מסוים ומציב לתחום אחר את ערך ההחזרה

נשתמש בו ובפונקצית הספריה שלC toupper)( כדי להמיר מחרוזת לאותיות גדולות

transform(str.begin(),str.end(),str.begin(),toupper);

Page 27: תרגול מס' 12

27מבוא לתכנות מערכות - 234122

כתיבת אלגוריתמים גנריים - סיכום

הספריה הסטנדרטית בנויה מאוספים ואלגוריתמיםאיטרטורים מהווים את הדבק המאפשר לשני חלקים אלו להישאר גנריים-משתמשים בFunction Objects כדי לאפשר שליחת פונקציות

לאלגוריתמים

אוספים איטרטוריםאלגוריתמים

Page 28: תרגול מס' 12

28מבוא לתכנות מערכות - 234122

מצביעים חכמים

smart_ptrshared_ptr

Page 29: תרגול מס' 12

29מבוא לתכנות מערכות - 234122

מצביעים חכמים

מצביעים אחראים לרובן המוחלט של שגיאות הזיכרון הצלחנו להיפטר מרוב השימושים הלא בטוחים במצביעים בעזרת שימוש

Cבתכונות של ++ניצול בנאים, הורסים והשמות לטיפול מסודר בזיכרון–

ואוספים לטיפול מסודר באלגוריתמים של מבני הנתוניםSTLשימוש ב-–

-אם ננסה להשתמש בהורשה ובvector:מתעוררת בעיה

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

צריך לנהל זיכרון בצורה מפורשת בכל מקום בתוכנית!–

vector<Shape> shapes;Circle circle(3.5);shapes.push_back(circle);

vector<Shape*> shapes;//...delete shapes.back();shapes.pop_back();

Page 30: תרגול מס' 12

30מבוא לתכנות מערכות - 234122

smart_ptrנוכל ליצור מחלקה, המתנהגת כמצביע אך מוסיפה התנהגות נוספת

למשל, שחרור העצם המוצבע–בזמן הריסת המצביע

כלומר ניצור מצביע "חכם" יותר

-מה קורה במקרה והnewהשני נכשל בכל אחת מהפונקציות?

template<typename T>class smart_ptr {

T* data;typedef T element_type;

public:explicit smart_ptr(T* ptr =

NULL) : data(ptr) {}

~smart_ptr() { delete data;}T& operator*() const {

return *data; }T* operator->() const

{ return data; }};

int bad() {Shape* ptr1 = new

Circle(5.0);Shape* ptr2 = new

Square(5.0);//...

}

int good() {smart_ptr<Shape>

ptr1(new Circle(5.0));smart_ptr<Shape>

ptr2(new Square(5.0));//...

}

Page 31: תרגול מס' 12

31מבוא לתכנות מערכות - 234122

העתקה

?כיצד יתנהג המצביע במקרה של העתקהמה צריכה להיות ההתנהגות עבור בנאי העתקה והשמה?–

ניסיון ראשון: העתקת המצביע תבצע "העברת בעלות" של העצםהמוצבע

C הקיים בספריה הסטנדרטית של ++auto_ptrהתנהגות זו ממומשת ב-–מאפשרת העברת/החזרת עצמים מוקצים דינאמית מפונקציות–

Page 32: תרגול מס' 12

32מבוא לתכנות מערכות - 234122

העתקה-שימוש בauto_ptr:כדי להחזיר עצם חדש

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

-שימוש בauto_ptr:כדי לחסוך העתקות

בעיה! ההתנהגות עבור "העתקה" שלauto_ptr ההעתק אינה סטנדרטית -אינו זהה למקור!

מאחר והם מסתמכים על תכונה זוSTL בתוך אוספים של ה-auto_ptrלא ניתן לאחסן –

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

auto_ptr<Shape> createMyShape() {return auto_ptr<Shape>(new Circle(5.0));

}

auto_ptr<vector<int> > getNPrimeNumbers (int n) {// ...

}

Page 33: תרגול מס' 12

33מבוא לתכנות מערכות - 234122

שיפור - מצביע משותף

:ניצור מצביע חכם יותר מתקדםshared_ptr

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

Object* ptrint*

counter

shared_ptr<Object>

Object* ptrint*

counter

shared_ptr<Object>

Object

2

Object* ptrint*

counter

shared_ptr<Object>Object

1

Page 34: תרגול מס' 12

34מבוא לתכנות מערכות - 234122

shared_ptrדוגמה - בעזרתshared_ptr לא נצטרך לדאוג יותר לזכור לשחרר מצביעים, כאשר

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

לדוגמה, בקוד הבא קשה לראות אילו עצמים יש לשחרר ומתי:–vector<shared_ptr<Shape> > function(const vector<Point>& points) {

shared_ptr<Shape> shape(new Polygon(points));shared_ptr<Circle> circle(new Circle(5.0));shared_ptr<Square> square(new Square(2.0));

vector<shared_ptr<Shape> > vec;vec.push_back(shape);vec.push_back(circle);vec.push_back(square);vector<shared_ptr<Shape> > copy = vec;copy.pop_back();return copy;

}

Page 35: תרגול מס' 12

35מבוא לתכנות מערכות - 234122

shared_ptrמימוש - template<typename T>

class shared_ptr {

private:

T* data;

int* counter;

 

typedef T element_type;

 

void checkInvariant() const {

assert((data && counter && *counter > 0) || (!data && !counter));

}

Page 36: תרגול מס' 12

36מבוא לתכנות מערכות - 234122

shared_ptrמימוש - void increaseCount() {

checkInvariant();if (counter) {

(*counter)++;}

void decreaseCount() {checkInvariant();if (counter && --*counter == 0) {

delete counter;delete data;counter = NULL;data = NULL;

}}

Page 37: תרגול מס' 12

37מבוא לתכנות מערכות - 234122

shared_ptrמימוש - public:

explicit shared_ptr(T* ptr = NULL) :data(ptr), counter(data ? new int(1) : NULL) {

shared_ptr(const shared_ptr<T>& other) :data(other.data), counter(other.counter) {increaseCount();checkInvariant();

template<typename S> friend class shared_ptr;template<typename S> shared_ptr(const shared_ptr<S>& other) :

data(other.data), counter(other.counter) {increaseCount();checkInvariant();

}

Page 38: תרגול מס' 12

38מבוא לתכנות מערכות - 234122

shared_ptrמימוש - ~shared_ptr() {

checkInvariant();decreaseCount();checkInvariant();

template<typename S> shared_ptr<T>& operator=(shared_ptr<S>& other) {

checkInvariant();

other.increaseCount();

decreaseCount();

counter = other.counter;

data = other.data;

checkInvariant();

return *this;

}

מדוע אין צורך בבדיקת הצבה עצמית?

Page 39: תרגול מס' 12

39מבוא לתכנות מערכות - 234122

shared_ptrמימוש - T& operator*() const {

checkInvariant();assert(data != NULL);return *data;

}

T* operator->() const {checkInvariant();assert(data != NULL);return data;

}

T* get() const {checkInvariant();return data;

)( מסופקת בכדי לאפשר שימוש של get המתודההמחלקה גם עם קוד ישן שאינו תומך

shared_ptrב-

Page 40: תרגול מס' 12

40מבוא לתכנות מערכות - 234122

shared_ptrמימוש - operator bool() {

checkInvariant();

return data;

}

 

void reset() {

decreaseCount();

data = NULL;

counter = NULL;

}

 

};

 

)( מאפשרת למשתמש resetהמתודה צורה נוחה יותר לאיפוס מצביע

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

מצביע רגיל.

Page 41: תרגול מס' 12

41מבוא לתכנות מערכות - 234122

shared_ptrמימוש - template<typename T, typename S>

bool operator==(const shared_ptr<T>& first, const shared_ptr<S>& second) {

return first.get() == second.get();

}

 

template<typename T, typename S>

bool operator!=(const shared_ptr<T>& first, const shared_ptr<S>& second) {

return !(first == second);

}

 

template<typename T, typename S>

bool operator<(const shared_ptr<T>& first, const shared_ptr<S>& second) {

return first.get() < second.get();

}

Page 42: תרגול מס' 12

42מבוא לתכנות מערכות - 234122

shared_ptrסיכום - :יתרונות

כל הקוד לניהול הזיכרון נכתב רק פעם אחת–

קל לחלוק עצמים אשר לא ברור מי האחרון שמשתמש בהם–

ניתן להשתמש בכל האוספים שראינו עם מצביעים ובפרט עם ירושות–

הקוד נהייה פשוט יותר ועמיד יותר בפני שגיאות זיכרון–

:עדיין קיימות מספר בעיות–shared_ptr!אינו מתאים לאחסון מצביע למערך

][delete ולא deleteכי השחרור הוא ע"י •

!vector שיתאים לבעיה זו, אבל ממילא עדיף shared_arrayניתן ליצור בקלות •

המצביעים לא ישוחררו אם קיימים קשרים מעגליים–

resetבמקרה זה יש לנקות את המצביעים בצורה מפורשת עם •פתרון טוב יותר למקרה זה דורש היכרות עם מצביע חכם נוסף והזמן קצר •

מלהכיל אותו