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.
Tack för dina kommentarer!
Fråga AI
Fråga AI
Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal
Awesome!
Completion rate improved to 14.29
Introduction to Smart Pointers
Svep för att visa menyn
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.
Tack för dina kommentarer!