Introduction to Smart Pointers
Smart pointers are special objects in C++ that help you manage dynamically allocated memory automatically, reducing the risk of memory leaks and dangling pointers. Two of the most widely used smart pointers are std::unique_ptr and std::shared_ptr. A unique_ptr owns its object exclusively—only one unique_ptr can point to a given resource at a time, and ownership can be transferred but never duplicated. When a unique_ptr goes out of scope, it deletes the managed object. In contrast, a shared_ptr allows multiple pointers to share ownership of the same object. The managed object is deleted only when the last shared_ptr owning it is destroyed or reset. This ownership model is implemented using reference counting, ensuring that memory is freed precisely when it is no longer needed.
main.cpp
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748#include <iostream> #include <memory> class Widget { public: Widget(int id) : id_(id) { std::cout << "Widget " << id_ << " constructed\n"; } ~Widget() { std::cout << "Widget " << id_ << " destructed\n"; } void greet() const { std::cout << "Hello from Widget " << id_ << "\n"; } private: int id_; }; void useUniquePtr() { std::unique_ptr<Widget> up1 = std::make_unique<Widget>(1); up1->greet(); // Transfer ownership to up2 std::unique_ptr<Widget> up2 = std::move(up1); if (!up1) { std::cout << "up1 no longer owns the Widget\n"; } up2->greet(); // up2 goes out of scope here, Widget is destroyed } void useSharedPtr() { std::shared_ptr<Widget> sp1 = std::make_shared<Widget>(2); { std::shared_ptr<Widget> sp2 = sp1; // sp1 and sp2 share ownership std::cout << "sp1 use_count: " << sp1.use_count() << "\n"; sp2->greet(); } // sp2 goes out of scope, but Widget is not destroyed yet std::cout << "sp1 use_count after sp2: " << sp1.use_count() << "\n"; sp1->greet(); // sp1 goes out of scope here, Widget is destroyed } int main() { useUniquePtr(); useSharedPtr(); return 0; }
You should use unique_ptr whenever you want exclusive ownership of a dynamically allocated object, as it is lightweight and prevents accidental sharing. shared_ptr is useful when ownership must be shared across multiple parts of your program. However, be careful: shared_ptr can introduce overhead due to reference counting, and careless use can lead to performance problems. One common pitfall is circular references, where two or more shared_ptr instances reference each other, preventing their memory from ever being released. To avoid this, use std::weak_ptr for non-owning references in such cases.
To explore smart pointers and memory management in greater depth, visit the Smart Pointers in Modern C++ course.
Merci pour vos commentaires !
Demandez à l'IA
Demandez à l'IA
Posez n'importe quelle question ou essayez l'une des questions suggérées pour commencer notre discussion
Can you give examples of how to use `unique_ptr` and `shared_ptr` in code?
What are some best practices for avoiding memory leaks with smart pointers?
Can you explain more about how `weak_ptr` helps prevent circular references?
Awesome!
Completion rate improved to 14.29
Introduction to Smart Pointers
Glissez pour afficher le menu
Smart pointers are special objects in C++ that help you manage dynamically allocated memory automatically, reducing the risk of memory leaks and dangling pointers. Two of the most widely used smart pointers are std::unique_ptr and std::shared_ptr. A unique_ptr owns its object exclusively—only one unique_ptr can point to a given resource at a time, and ownership can be transferred but never duplicated. When a unique_ptr goes out of scope, it deletes the managed object. In contrast, a shared_ptr allows multiple pointers to share ownership of the same object. The managed object is deleted only when the last shared_ptr owning it is destroyed or reset. This ownership model is implemented using reference counting, ensuring that memory is freed precisely when it is no longer needed.
main.cpp
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748#include <iostream> #include <memory> class Widget { public: Widget(int id) : id_(id) { std::cout << "Widget " << id_ << " constructed\n"; } ~Widget() { std::cout << "Widget " << id_ << " destructed\n"; } void greet() const { std::cout << "Hello from Widget " << id_ << "\n"; } private: int id_; }; void useUniquePtr() { std::unique_ptr<Widget> up1 = std::make_unique<Widget>(1); up1->greet(); // Transfer ownership to up2 std::unique_ptr<Widget> up2 = std::move(up1); if (!up1) { std::cout << "up1 no longer owns the Widget\n"; } up2->greet(); // up2 goes out of scope here, Widget is destroyed } void useSharedPtr() { std::shared_ptr<Widget> sp1 = std::make_shared<Widget>(2); { std::shared_ptr<Widget> sp2 = sp1; // sp1 and sp2 share ownership std::cout << "sp1 use_count: " << sp1.use_count() << "\n"; sp2->greet(); } // sp2 goes out of scope, but Widget is not destroyed yet std::cout << "sp1 use_count after sp2: " << sp1.use_count() << "\n"; sp1->greet(); // sp1 goes out of scope here, Widget is destroyed } int main() { useUniquePtr(); useSharedPtr(); return 0; }
You should use unique_ptr whenever you want exclusive ownership of a dynamically allocated object, as it is lightweight and prevents accidental sharing. shared_ptr is useful when ownership must be shared across multiple parts of your program. However, be careful: shared_ptr can introduce overhead due to reference counting, and careless use can lead to performance problems. One common pitfall is circular references, where two or more shared_ptr instances reference each other, preventing their memory from ever being released. To avoid this, use std::weak_ptr for non-owning references in such cases.
To explore smart pointers and memory management in greater depth, visit the Smart Pointers in Modern C++ course.
Merci pour vos commentaires !