Home >Backend Development >C++ >How to Safely Downcast a Unique Pointer of Base to a Unique Pointer of Derived?

How to Safely Downcast a Unique Pointer of Base to a Unique Pointer of Derived?

Mary-Kate Olsen
Mary-Kate OlsenOriginal
2024-12-03 03:16:10478browse

How to Safely Downcast a Unique Pointer of Base to a Unique Pointer of Derived?

Downcasting from Unique Pointer of Base to Unique Pointer of Derived

When working with class hierarchies and inheritance, it may be necessary to downcast a unique pointer from a base class to a derived class to access specific functionality. This is commonly encountered when a factory method returns a unique pointer to the base class but the actual object is of a derived type.

To perform downcasting, it is often recommended to follow a two-step approach. First, release the object from the unique pointer using its release() method. This frees the underlying resource and returns a raw pointer to the derived class object. Secondly, use a function to cast the raw pointer to the desired derived class and reassign it to a new unique pointer.

Here's an example of a CastToDerived() function that performs a safe downcast:

template<typename Derived, typename Base>
std::unique_ptr<Derived> CastToDerived(Base* obj) {
    return std::unique_ptr<Derived>(static_cast<Derived*>(obj));
}

This function can be employed to downcast from a base class unique pointer to a derived class unique pointer:

unique_ptr<Derived> ptr = CastToDerived(DerivedAFactory());

Alternatively, if static casting is unreliable, you can use the following function templates, which perform static or dynamic casts based on the type safety of the downcast:

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 functions ensure that the resource is disposed of properly and the unique pointer is constructed with the appropriate deleter function.

The above is the detailed content of How to Safely Downcast a Unique Pointer of Base to a Unique Pointer of Derived?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn