Middle
Πώς λειτουργεί το shared_ptr στην C++;
sobes.tech AI
Απάντηση από AI
shared_ptr — είναι ένας έξυπνος δείκτης που υλοποιεί την σημασιολογία ιδιοκτησίας ενός κοινόχρηστου πόρου. Αποθηκεύει έναν δείκτη στο αντικείμενο και έναν δείκτη στο μπλοκ ελέγχου.
Το μπλοκ ελέγχου περιέχει:
- Μετρητή ισχυρών αναφορών (reference count).
- Μετρητή αδύναμων αναφορών (weak count).
- Προσαρμοσμένο functor διαγραφής (deleter), αν οριστεί.
- Προσαρμοστικό allocator, αν οριστεί.
- Δείκτη στο αποθηκευμένο αντικείμενο (το ίδιο με αυτό που αποθηκεύεται στο
shared_ptr).
Αρχή λειτουργίας:
- Δημιουργία: Κατά τη δημιουργία του πρώτου
shared_ptrπου δείχνει σε ένα αντικείμενο, δημιουργείται το μπλοκ ελέγχου και αρχικοποιούνται οι μετρητές αναφορών: ισχυροί — 1, αδύναμοι — 0.std::shared_ptr<int> ptr1 = std::make_shared<int>(10); // Δημιουργεί ένα αντικείμενο int και ένα μπλοκ ελέγχου - Αντιγραφή: Κατά την αντιγραφή ενός
shared_ptr, ο μετρητής ισχυρών αναφορών στο μπλοκ ελέγχου αυξάνεται κατά 1.std::shared_ptr<int> ptr2 = ptr1; // Αυξάνει τον μετρητή ισχυρών αναφορών - Ανάθεση: Κατά την ανάθεση ενός
shared_ptr, η παλιά πόρος μειώνεται (ο μετρητής ισχυρών αναφορών μειώνεται), και ο νέος πόρος αυξάνεται (αυξάνεται).std::shared_ptr<int> ptr3; ptr3 = ptr1; // Μειώνει τον παλιό πόρο του ptr3, αυξάνει τον πόρο του ptr1 - Διαγραφή: Κατά την καταστροφή ενός
shared_ptr(π.χ., έξοδος από το scope), ο μετρητής ισχυρών αναφορών μειώνεται.{ std::shared_ptr<int> ptr4 = ptr1; // Αυξάνει τον μετρητή ισχυρών αναφορών // το ptr4 βγαίνει από το scope } // Μειώνει τον μετρητή ισχυρών αναφορών - Απελευθέρωση του πόρου: Όταν ο μετρητής ισχυρών αναφορών φτάσει στο μηδέν, ο πόρος (το αντικείμενο που δείχνει το
shared_ptr) διαγράφεται χρησιμοποιώντας το καθορισμένο functor διαγραφής (ήdeleteκατά προεπιλογή). - Απελευθέρωση του μπλοκ ελέγχου: Το μπλοκ ελέγχου απελευθερώνεται όταν και οι δύο μετρητές (ισχυρός και αδύναμος) φτάσουν στο μηδέν.
Πλεονεκτήματα:
- Αυτόματη διαχείριση μνήμης για κοινόχρηστους πόρους.
- Ασφάλεια από διπλή απελευθέρωση.
- Υποστήριξη για προσαρμοσμένους functors διαγραφής.
Μειονεκτήματα:
- Οι κυκλικοί σύνδεσμοι μπορούν να οδηγήσουν σε διαρροές μνήμης (
weak_ptr). - Μικρή αύξηση κόστους λόγω του μπλοκ ελέγχου και των ατομικών λειτουργιών στους μετρητές.
- Ασφάλεια στις λειτουργίες με το ίδιο
shared_ptr(αντιγραφή, ανάθεση, αλλαγή δείκτη), αλλά όχι με το αντικείμενο στο οποίο δείχνει.