Home >Backend Development >C++ >How to Safely Downcast a `unique_ptr` from Base to Derived in C ?
How to Downcast a unique_ptr from Base to Derived
In object-oriented programming, it is common to use class hierarchies to represent real-world concepts. In C , this is often done using inheritance. Inheritance allows a derived class to inherit the properties and behavior of its base class.
One common need when working with class hierarchies is to convert a pointer to a base class into a pointer to a derived class. This process is known as downcasting.
In the context of unique pointers, downcasting can be a bit tricky. This is because unique pointers are designed to prevent dangling pointers and other memory issues. As a result, you cannot simply use a static_cast to convert a unique_ptr to a different type.
Instead, you must use one of the following methods:
1. Static Unique Pointer Cast
This method can be used when you are certain that the unique pointer actually contains a pointer to a derived class. The following function template can be used to perform a static unique pointer cast:
template<typename Derived, typename Base, typename Del> std::unique_ptr<Derived, Del> static_unique_ptr_cast(std::unique_ptr<Base, Del> &&p) { auto d = static_cast<Derived *>(p.release()); return std::unique_ptr<Derived, Del>(d, std::move(p.get_deleter())); }
2. Dynamic Unique Pointer Cast
This method can be used when you are not certain that the unique pointer contains a pointer to a derived class. The following function template can be used to perform a dynamic unique pointer cast:
template<typename Derived, typename Base, typename Del> std::unique_ptr<Derived, Del> dynamic_unique_ptr_cast(std::unique_ptr<Base, Del> &&p) { if (Derived *result = dynamic_cast<Derived *>(p.get())) { p.release(); return std::unique_ptr<Derived, Del>(result, std::move(p.get_deleter())); } return std::unique_ptr<Derived, Del>(nullptr, p.get_deleter()); }
Example
The following code demonstrates how to use the static unique pointer cast to convert a unique_ptr to a different type:
#include <memory> class Base { public: virtual ~Base() {} }; class Derived : public Base { public: ~Derived() {} }; int main() { std::unique_ptr<Base> uptr = std::make_unique<Derived>(); std::unique_ptr<Derived> dptr = static_unique_ptr_cast<Derived>(std::move(uptr)); return 0; }
In this example, we create a unique_ptr to a Base object. We then use the static unique pointer cast to convert the unique_ptr to a unique_ptr to a Derived object. This is possible because we know that the unique_ptr to the Base object actually contains a pointer to a Derived object.
The above is the detailed content of How to Safely Downcast a `unique_ptr` from Base to Derived in C ?. For more information, please follow other related articles on the PHP Chinese website!