Κοινή χρήση τεχνολογίας

【C】Έξυπνος δείκτης

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Οι έξυπνοι δείκτες εξηγούνται

Το Smart Pointer είναι ένα εργαλείο σε C++ που χρησιμοποιείται για την αυτόματη διαχείριση δυναμικά εκχωρημένης μνήμης.

Είναι μια κλάση που ενσωματώνει τις λειτουργίες των ακατέργαστων δεικτών και μπορεί να χειριστεί αυτόματα την κατανομή και την αποδέσμευση πόρων, βοηθώντας έτσι τους προγραμματιστές να αποφύγουν κοινά σφάλματα διαχείρισης μνήμης, όπως διαρροές μνήμης, κρεμαστές δείκτες και άλλα προβλήματα.

Οι έξυπνοι δείκτες λειτουργούν μέσω του μηχανισμού Resource Acquisition Is Initialization (RAII), που σημαίνει ότι οι έξυπνοι δείκτες αποκτούν πόρους όταν κατασκευάζονται και απελευθερώνουν πόρους όταν καταστρέφονται. Αυτό διασφαλίζει ότι οι πόροι αποδεσμεύονται σωστά ακόμη και υπό μη φυσιολογικές συνθήκες.

 

Προβλήματα που λύνονται με έξυπνους δείκτες

(1) Διαρροή μνήμης: Η μνήμη απελευθερώνεται χειροκίνητα, αλλά μπορεί να απελευθερωθεί αυτόματα χρησιμοποιώντας έξυπνους δείκτες.

(2) Διάδοση και απελευθέρωση δεικτών κοινής ιδιοκτησίας, όπως ζητήματα καταστροφής όταν πολλά νήματα χρησιμοποιούν το ίδιο αντικείμενο.

 

Διάφοροι τύποι έξυπνων δεικτών

Η τυπική βιβλιοθήκη C++ παρέχει διάφορους τύπους έξυπνων δεικτών, όπως:

  1. std::unique_ptr

    • Μοντέλο αποκλειστικής ιδιοκτησίας, που σημαίνει αunique_ptrΈνα στιγμιότυπο έχει αποκλειστική ιδιοκτησία του αντικειμένου στο οποίο υποδεικνύει.
    • πότεunique_ptrΌταν ξεφεύγει από το πεδίο εφαρμογής ή γίνεται ρητά επαναφορά, καλεί αυτόματα τον καταστροφέα και απελευθερώνει το διαχειριζόμενο αντικείμενο.
    • Η αντιγραφή δεν υποστηρίζεται, αλλά είναι δυνατή η μετακίνηση.
  2. std::shared_ptr

    • Μοντέλο κοινής ιδιοκτησίας, επιτρέποντας πολλαπλάshared_ptrΟι περιπτώσεις μοιράζονται την ιδιοκτησία του ίδιου αντικειμένου.
    • Χρησιμοποιήστε την καταμέτρηση αναφορών για να παρακολουθήσετε αναφορές στο ίδιο αντικείμενοshared_ptrποσότητα.
    • όταν το τελευταίοshared_ptrΌταν ένα στιγμιότυπο ξεφεύγει από το πεδίο εφαρμογής ή γίνεται επαναφορά, το πλήθος αναφοράς μειώνεται στο μηδέν, καλείται ο καταστροφέας του αντικειμένου και το αντικείμενο απελευθερώνεται.
  3. std::weak_ptr

    • χρησιμοποιείται για την επίλυσηshared_ptrπρόβλημα κυκλικής αναφοράς.
    • Χωρίς αύξηση του αριθμού αναφοράς, μπορεί να παρατηρηθεί μεshared_ptrδιαχειριζόμενα αντικείμενα, αλλά δεν συμμετέχει στη διαχείριση του κύκλου ζωής του.
    • Όταν δεν υπάρχειshared_ptrΌταν ένα παράδειγμα δείχνει σε ένα αντικείμενο,weak_ptrΜπορεί να ανιχνεύσει ότι το αντικείμενο έχει καταστραφεί.

Ο σχεδιασμός και η χρήση έξυπνων δεικτών απλοποιεί σημαντικά τη διαχείριση της μνήμης στη C++ και βελτιώνει την ευρωστία και την ασφάλεια του προγράμματος. Στον σύγχρονο προγραμματισμό C++, συνιστάται ιδιαίτερα η χρήση έξυπνων δεικτών αντί για ακατέργαστους δείκτες για τη βελτίωση της ποιότητας και της δυνατότητας συντήρησης του κώδικα.

 

Παράδειγμα έξυπνου δείκτη

Οι έξυπνοι δείκτες χρησιμοποιούνται στη C++ ως μέσο για την αυτόματη διαχείριση δυναμικά εκχωρημένης μνήμης για την αποφυγή διαρροών μνήμης και άλλων ζητημάτων που σχετίζονται με τη διαχείριση πόρων.

std::unique_ptrΠαράδειγμα

std::unique_ptrείναι ένας έξυπνος δείκτης με αποκλειστική ιδιοκτησία, που διασφαλίζει ότι υπάρχει μόνο έναςstd::unique_ptr Ένα παράδειγμα έχει τον έλεγχο ενός δεδομένου πόρου.πότεstd::unique_ptrΌταν ξεφεύγει από το πεδίο εφαρμογής ή γίνει επαναφορά, οι πόροι που κατέχει θα αποδεσμευτούν αυτόματα.

  1. #include <memory>
  2. class MyClass {
  3. public:
  4. MyClass() { std::cout << "MyClass constructor called.n"; }
  5. ~MyClass() { std::cout << "MyClass destructor called.n"; }
  6. void doSomething() { std::cout << "Doing something...n"; }
  7. };
  8. int main() {
  9. // 创建一个unique_ptr来管理MyClass的实例
  10. std::unique_ptr<MyClass> uptr(new MyClass());
  11. // 调用doSomething方法
  12. uptr->doSomething();
  13. // unique_ptr会在离开作用域时自动调用MyClass的析构函数
  14. return 0;
  15. }

std::shared_ptrΠαράδειγμα

std::shared_ptrείναι ένας έξυπνος δείκτης κοινής ιδιοκτησίας που επιτρέπει πολλαπλούςstd::shared_ptrΟι παρουσίες μοιράζονται την ιδιοκτησία του ίδιου πόρου.std::shared_ptrΧρησιμοποιήστε ένα πλήθος αναφοράς για να παρακολουθήσετε πόσοι έξυπνοι δείκτες δείχνουν προς τον ίδιο πόρο Όταν ο αριθμός αναφοράς φτάσει στο 0, ο πόρος απελευθερώνεται.

  1. #include <memory>
  2. class MyClass {
  3. public:
  4. MyClass() { std::cout << "MyClass constructor called.n"; }
  5. ~MyClass() { std::cout << "MyClass destructor called.n"; }
  6. void doSomething() { std::cout << "Doing something...n"; }
  7. };
  8. int main() {
  9. // 创建一个shared_ptr来管理MyClass的实例
  10. std::shared_ptr<MyClass> sptr(new MyClass());
  11. // 创建第二个shared_ptr,共享同一个MyClass实例
  12. std::shared_ptr<MyClass> sptr2 = sptr;
  13. // 调用doSomething方法
  14. sptr->doSomething();
  15. // 当所有shared_ptr实例都超出作用域时,MyClass的析构函数才会被调用
  16. return 0;
  17. }

 

Προφυλάξεις

Σε χρήσηstd::shared_ptr Όταν το κάνετε αυτό, προσέξτε να αποφύγετε κυκλικές καταστάσεις αναφοράς, οι οποίες θα κάνουν το πλήθος αναφοράς να μην πέσει ποτέ στο 0, οδηγώντας σε διαρροές πόρων.Στην περίπτωση κυκλικών αναφορών, μπορείτε να χρησιμοποιήσετεstd::weak_ptrνα σπάσουμε τον κύκλο,std::weak_ptrΔεν αυξάνει το πλήθος αναφοράς, διατηρεί μόνο τοstd::shared_ptrΔιαχειριστείτε αδύναμες αναφορές σε πόρους.

Αυτά τα παραδείγματα δείχνουν πώς να χρησιμοποιείτε έξυπνους δείκτες για τη διαχείριση δυναμικά εκχωρημένης μνήμης για να διασφαλίσετε ότι οι πόροι αποδεσμεύονται σωστά την κατάλληλη στιγμή, αποφεύγοντας κοινά λάθη που μπορεί να προκύψουν κατά τη μη αυτόματη διαχείριση της μνήμης.

 

Άλλα παραδείγματα

https://www.cnblogs.com/god-of-death/p/17962676

https://zhuanlan.zhihu.com/p/678722914