Home > Article > Backend Development > How to Safely Downcast a `unique_ptr` to `unique_ptr` in C ?
Downcasting unique_ptr
In the realm of object-oriented programming, inheritance plays a pivotal role in fostering code reuse and extensibility. However, situations may arise where one needs to "downcast" a unique_ptr
To address this challenge, consider a hypothetical scenario where an application employs several factories, each producing unique_ptr
unique_ptr<Base> DerivedAFactory() { return unique_ptr<Base>(new DerivedA); }
The goal is to convert the pointer within the returned unique_ptr
unique_ptr<Derived> ptr = static_cast<unique_ptr<Derived>>(DerivedAFactory());
However, this approach presents potential pitfalls. A more robust solution involves releasing the object from the unique_ptr
unique_ptr<Derived> CastToDerived(Base* obj) { return unique_ptr<Derived>(static_cast<Derived*>(obj)); }
This casting process should hold valid as long as the object is dynamically loaded from a DLL and released from the same context. However, when transferring ownership across different contexts, one must take care to supply a correct deleter alongside the pointer.
For added safety and flexibility, it is recommended to utilize function templates for casting:
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())); } 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()); }
These templates ensure that the passed unique_ptr is not unintentionally stolen from the caller while providing both static and dynamic casting options. The static version can be employed when the pointer is known to be a Derived * without dynamic casting, while the dynamic version performs a runtime check using dynamic_cast.
The above is the detailed content of How to Safely Downcast a `unique_ptr` to `unique_ptr` in C ?. For more information, please follow other related articles on the PHP Chinese website!