Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Real-World Applications of Smart Pointers | Advanced topics
C++ Smart Pointers
course content

Course Content

C++ Smart Pointers

C++ Smart Pointers

1. Introduction to Smart Pointers
2. Unique Pointers
3. Shared Pointers
4. Weak Pointers
5. References
6. Advanced topics

bookReal-World Applications of Smart Pointers

Smart pointers play a crucial role in modern C++ development. They don’t just offer dynamic memory management, but also enable efficient and safe handling of various real-world scenarios. Let's explore some advanced applications of std::unique_ptr, std::shared_ptr, and std::weak_ptr in practical contexts.

Shared pointers

Shared pointers excel in all areas where resource sharing is needed. Consider a scenario where multiple components in a system need access to a shared resource, like a database connection. We can use a shared pointer in this case for efficient management and cleanup of the connection.

cpp

main

copy
123456789101112131415161718192021222324252627
#include <memory> #include <iostream> class Database { // Database implementation }; class Component { public: //each component holds a shared pointer to the same resource std::shared_ptr<Database> db_ptr; Component(std::shared_ptr<Database> db) : db_ptr(db) {} // Other component functionalities }; int main() { std::shared_ptr<Database> db = std::make_shared<Database>(); // Different components using the same database Component component1(db); Component component2(db); // Simulate different component usage component1.db_ptr.reset(); // Resets usage in component 1 // component2 still holds a reference to the database }

In the above example, we create a single database resource which is shared by different components. Each component contains a shared pointer that points to the same resource. This is a safe way to share the database resource because it ensures that the database stays alive for as long as there’s a shared pointer pointing to it.

Unique pointers

If you are managing some objects using a container, like a vector, the implementation can be made more robust using unique pointers. Consider this example:

cpp

main

copy
12345678910111213141516
#include <memory> #include <vector> #include <iostream> class Widget { public: ~Widget() { std::cout <<"Widget object destroyed." << std::endl; } }; int main() { std::vector<std::unique_ptr<Widget>> widgetContainer; widgetContainer.push_back(std::make_unique<Widget>()); widgetContainer.push_back(std::make_unique<Widget>()); // Proper cleanup upon container destruction widgetContainer.clear(); // Widgets are automatically deallocated }

In our above example, we simulate a vector that contains several dynamically allocated widgets. Since these widgets don’t have to be shared, we don’t need a shared pointer here. All we need is a unique pointer that ensures that every single widget gets properly deallocated when the vector is cleared.

If you run the above program, you will see the destructor being automatically called for both the widget objects.

Weak pointers

In graph data structures, nodes can reference each other, which can potentially lead to cyclic references. We can use weak pointers to break these cycles and prevent memory leaks.

In the above snippet, we use a weak pointer to avoid creating a cyclic reference in a graph. To access the node and perform an operation, we convert the weak pointer to a shared pointer.

Everything was clear?

How can we improve it?

Thanks for your feedback!

Section 6. Chapter 2
some-alt