Middle
Πώς λειτουργεί το unique_ptr στην C++;
sobes.tech AI
Απάντηση από AI
std::unique_ptr — είναι ένας έξυπνος δείκτης που υλοποιεί την αποκλειστική ιδιοκτησία ενός δυναμικά κατανεμημένου αντικειμένου. Παρέχει αυτόματη διαχείριση μνήμης: το αντικείμενο στο οποίο δείχνει το unique_ptr διαγράφεται αυτόματα κατά τη καταστροφή του unique_ptr.
Βασικά χαρακτηριστικά:
- Αποκλειστική ιδιοκτησία: Σε οποιαδήποτε στιγμή, μόνο ένα
unique_ptrμπορεί να κατέχει ένα συγκεκριμένο αντικείμενο. - Χωρίς αντιγραφή: Το
unique_ptrδεν μπορεί να αντιγραφεί. Αυτό αποτρέπει την πολλαπλή ιδιοκτησία του ίδιου αντικειμένου και το πρόβλημα της "διπλής διαγραφής". - Μεταβατική σημασιολογία: Η ιδιοκτησία του αντικειμένου μπορεί να μεταφερθεί από ένα
unique_ptrσε άλλο χρησιμοποιώντας τη σημασιολογία μεταφοράς (std::move). - Ρυθμιζόμενος διαγραφέας: Μπορείτε να παρέχετε έναν δικό σας διαγραφέα για να διαχειριστείτε συγκεκριμένους τρόπους απελευθέρωσης πόρων.
Η αρχή λειτουργίας βασίζεται στο RAII (Resource Acquisition Is Initialization): ο πόρος (δυναμικά κατανεμημένη μνήμη) αποκτάται κατά τη δημιουργία του αντικειμένου (unique_ptr) και απελευθερώνεται κατά την καταστροφή του.
#include <memory> // Για unique_ptr
#include <iostream>
class MyClass {
public:
MyClass() { std::cout << "MyClass δημιουργήθηκε\n"; }
~MyClass() { std::cout << "MyClass διαγράφηκε\n"; }
};
int main() {
{
// Δημιουργία ενός unique_ptr που κατέχει ένα αντικείμενο MyClass
std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>();
// Αυτή τη στιγμή, το ptr1 είναι ο αποκλειστικός ιδιοκτήτης του αντικειμένου
// auto ptr2 = ptr1; // Σφάλμα μεταγλώττισης: απαγορεύεται η αντιγραφή
// Μεταφορά ιδιοκτησίας από ptr1 σε ptr2
std::unique_ptr<MyClass> ptr2 = std::move(ptr1);
// Μετά τη μεταφορά, το ptr1 δεν κατέχει πλέον το αντικείμενο (γίνεται nullptr)
if (!ptr1) {
std::cout << "ptr1 δεν κατέχει αντικείμενο: " << (ptr1 ? "Ναι" : "Όχι") << "\n";
}
// Η διάρκεια ζωής του ptr2 τελειώνει εδώ.
// το ptr2 καταστρέφεται και το αντικείμενο MyClass που κατείχε διαγράφεται αυτόματα.
} // Το αντικείμενο MyClass διαγράφεται εδώ
std::cout << "Τέλος main.\n";
return 0;
}
Σε σύγκριση με τον raw δείκτη:
| Χαρακτηριστικό | raw pointer |
std::unique_ptr |
|---|---|---|
| Ιδιοκτησία πόρου | Δεν ορίζεται | Εξατομικευμένη |
| Αυτόματη διαγραφή | Όχι | Ναι |
| Σημασιολογία αντιγραφής | Ναι | Όχι (μόνο μεταφορά) |
| Κίνδυνος διαρροής μνήμης | Υψηλός | Χαμηλός |
Γενικά, το unique_ptr είναι η προτιμώμενη μέθοδος διαχείρισης δυναμικής μνήμης σε C++11 και άνω, όταν απαιτείται αυστηρή ιδιοκτησία και αυτόματη απελευθέρωση πόρων.