Course Content
C++ Smart Pointers
C++ Smart Pointers
Best Practices of Using Shared Pointers
Only use shared pointers when you can’t use unique
Unique pointers should always be your first consideration when allocating a dynamic object. Only revert to shared pointers if you can justify the need for sharing.
Initialize shared pointers at the point of declaration
To enhance code readability and maintainability, it’s recommended to initialize a shared pointer when you declare it. This practice ensures that the shared pointer points to a valid object from the start and reduces the chances of accessing a null or uninitialized pointer.
good
bad
#include <memory> int main() { // Initializing the shared pointer when declaring it std::shared_ptr<int> ptr = std::make_shared<int>(10); // Now, the shared pointer points to a valid object and can be safely dereferenced *ptr += 5; }
Minimize the shared scope
While it's generally safe to use shared pointers, it's essential to exercise caution when sharing them. Strive to keep the scope of shared pointers as narrow as possible. This will ensure that they are released as soon as they are no longer needed.
Beware of circular references
Circular references occur when a group of shared pointers form a loop. Each shared pointer references the next one, and the last shared pointer in the loop goes back to the first one. This leads to a closed circle of references, where the reference count never goes to 0. Consider the following example:
main
#include <iostream> #include <memory> class Node { public: //shared pointer to the next element std::shared_ptr<Node> next; //the constructor Node() { std::cout << "Node constructed." << std::endl; } //the destructor ~Node() { std::cout << "Node destructed." << std::endl; } }; int main() { //creating three Node objects std::shared_ptr<Node> node1 = std::make_shared<Node>(); std::shared_ptr<Node> node2 = std::make_shared<Node>(); std::shared_ptr<Node> node3 = std::make_shared<Node>(); // Creating a circular reference node1->next = node2; node2->next = node3; node3->next = node1; // Destructors will not get called because of circular references }
In the code above, we have three Node
objects, which represent connected elements in a linked list. Each Node
has a next
member, which is a shared pointer pointing to the next element in the linked list.
Thanks for your feedback!