Με ποια βάση μπορούν πολλά αντικείμενα shared_ptr να αναφέρονται στην ίδια δείκτη;
sobes.tech AI
Απάντηση από AI
Πολλά αντικείμενα std::shared_ptr μπορούν να αναφέρονται στην ίδια δείκτη χάρη στην ύπαρξη ενός control block (control block).
Το control block που σχετίζεται με το διαχειριζόμενο αντικείμενο περιέχει:
- Μετρητή ισχυρών αναφορών (strong reference count): Αυξάνεται κατά τη δημιουργία ενός νέου
shared_ptrγια το ίδιο αντικείμενο. Μειώνεται κατά την καταστροφή ενόςshared_ptr. Όταν φτάσει το μηδέν, το συσχετιζόμενο αντικείμενο (δείκτης) διαγράφεται. - Μετρητή αδύναμων αναφορών (weak reference count): Χρησιμοποιείται για
std::weak_ptr. Αυξάνεται κατά τη δημιουργία ενόςweak_ptrαπό έναshared_ptr. Μειώνεται κατά την καταστροφή ενόςweak_ptr. Όταν και οι δύο μετρητές φτάσουν το μηδέν, το control block διαγράφεται. - Ιδιωτικός δείκτης στο διαχειριζόμενο αντικείμενο: Όχι ο δείκτης δεδομένων, αλλά αυτός που διαχειρίζεται το control block.
Όταν δημιουργείτε ένα shared_ptr από ένα υπάρχον shared_ptr (αντιγραφή, ανάθεση-αντιγραφή), και οι δύο αρχίζουν να χρησιμοποιούν το ίδιο control block, και ο μετρητής ισχυρών αναφορών σε αυτό το block αυξάνεται.
Παράδειγμα:
#include <memory>
#include <iostream>
struct MyData {
int value;
MyData(int v) : value(v) { std::cout << "MyData(" << value << ") created.\n"; }
~MyData() { std::cout << "MyData(" << value << ") destroyed.\n"; }
};
int main() {
// Δημιουργείται το πρώτο shared_ptr.
// Δημιουργείται το control block και το αντικείμενο MyData.
// Μετρητές: ισχυρός: 1, αδύναμος: 0.
std::shared_ptr<MyData> ptr1 = std::make_shared<MyData>(10);
std::cout << "μετρητής χρήσης ptr1: " << ptr1.use_count() << "\n";
// Δημιουργείται ένα δεύτερο shared_ptr από το ptr1.
// Χρησιμοποιεί το ίδιο control block.
// Ο μετρητής ισχυρών αυξάνεται σε 2.
std::shared_ptr<MyData> ptr2 = ptr1;
std::cout << "μετρητής χρήσης ptr1: " << ptr1.use_count() << "\n";
std::cout << "μετρητής χρήσης ptr2: " << ptr2.use_count() << "\n";
// Δημιουργείται ένα τρίτο shared_ptr από το ptr1.
// Χρησιμοποιεί το ίδιο control block.
// Ο μετρητής ισχυρών αυξάνεται σε 3.
std::shared_ptr<MyData> ptr3 = ptr1;
std::cout << "μετρητής χρήσης ptr1: " << ptr1.use_count() << "\n";
std::cout << "μετρητής χρήσης ptr2: " << ptr2.use_count() << "\n";
std::cout << "μετρητής χρήσης ptr3: " << ptr3.use_count() << "\n";
std::cout << "Έξοδος από το scope.\n";
// ptr3 βγαίνει από το scope.
// Ο μετρητής ισχυρών μειώνεται σε 2.
// ptr2 βγαίνει από το scope.
// Ο μετρητής ισχυρών μειώνεται σε 1.
// ptr1 βγαίνει από το scope.
// Ο μετρητής ισχυρών μειώνεται σε 0.
// Το αντικείμενο MyData διαγράφεται.
// Το control block διαγράφεται.
}
Κάθε αντικείμενο shared_ptr περιέχει τον δικό του δείκτη στο control block και τον δικό του δείκτη στο αντικείμενο δεδομένων. Κατά την αντιγραφή ενός shared_ptr, αντιγράφονται και οι δύο δείκτες, και ο μετρητής ισχυρών αναφορών στο κοινό control block αυξάνεται. Με αυτόν τον τρόπο, όλα τα shared_ptr δείχνουν στο ίδιο control block, το οποίο παρακολουθεί τον αριθμό των αντιγράφων που κατέχουν τον πόρο και καθορίζει τη στιγμή καταστροφής του διαχειριζόμενου πόρου.