Sobes.tech
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 και άνω, όταν απαιτείται αυστηρή ιδιοκτησία και αυτόματη απελευθέρωση πόρων.