简体   繁体   中英

Is it possible to return a reference to the result of a static or dynamic pointer cast?

so let's say I have the following function:

    template<typename T>
    std::shared_ptr<T> resourceAs() const {
        return std::static_pointer_cast<T>(m_resource);
    }

This works. But what if I don't like the small overhead of creating the shared_ptr? What if I want something like this

    template<typename T>
    const std::shared_ptr<T>& resourceAs() const {
        return std::static_pointer_cast<T>(m_resource);
    }

So, the problem here is that the compiler will be unhappy with me returning a local variable. Is there a safe way of returning a reference to a casted pointer of my member type? My instinct tells me no, but I'm pretty curious.

std::static_pointer_cast<T>(m_resource);

This function call returns an object, and not a reference to an object.

std::static_pointer_cast takes an existing std::shared_ptr as a parameter, and creates a new std::shared_ptr object (for a particular purpose which is not germane). It does not return a reference to an existing std::shared_ptr , but a new std::shared_ptr object.

Consequently if what's returned from std::static_pointer_cast<T> is stored in some variable, then that's what happens. If not, it gets destroyed.

In C++ obtaining a reference to an object does not prevent the underlying object from getting destroyed when it normally gets destroyed (there is one pedantic exception to this rule, the temporary object lifetime extension rule, but it does not apply here).

Your attempted, alternative resourceAs() obtains a reference to the returned std::shared_ptr , and returns it. But, since this std::shared_ptr (that's returned from std::static_pointer_cast ) does not actually gets stored anywhere it then gets destroyed, just like any other object that's declared local to resourceAs() would get destroyed, upon return from this function.

This is not something specific to std::shared_ptr , this is how all objects work in C++ and the same thing would happen to any other object in C++ that charters the same course:

class apple {

     // ...

};

apple buy_a_fruit();

const apple &what_i_bought()
{
     return buy_a_fruit();
}

what_i_bought() returns a reference to an object that's returned from buy_a_fruit() , but the object itself gets destroyed, leaving you with a reference to a destroyed object.

There is no valid usage of the resulting reference. Modern C++ compilers are smart enough to detect this mistake and issue a diagnostic alert.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM