std::unique_ptr with derived class
38,639
If they are polymorphic types and you only need a pointer to the derived type use dynamic_cast
:
Derived *derivedPointer = dynamic_cast<Derived*>(basePointer.get());
If they are not polymorphic types only need a pointer to the derived type use static_cast
and hope for the best:
Derived *derivedPointer = static_cast<Derived*>(basePointer.get());
If you need to convert a unique_ptr
containing a polymorphic type:
Derived *tmp = dynamic_cast<Derived*>(basePointer.get());
std::unique_ptr<Derived> derivedPointer;
if(tmp != nullptr)
{
basePointer.release();
derivedPointer.reset(tmp);
}
If you need to convert unique_ptr
containing a non-polymorphic type:
std::unique_ptr<Derived>
derivedPointer(static_cast<Derived*>(basePointer.release()));
Related videos on Youtube
![Lukas Schmit](https://i.stack.imgur.com/Iy0Zf.png?s=256&g=1)
Author by
Lukas Schmit
Updated on July 04, 2020Comments
-
Lukas Schmit almost 4 years
I have a question about the c++11 pointers. Specifically, how do you turn a unique pointer for the base class into the derived class?
class Base { public: int foo; } class Derived : public Base { public: int bar; } ... std::unique_ptr<Base> basePointer(new Derived); // now, how do I access the bar member?
it should be possible, but I can't figure out how. Every time I try using the
basePointer.get()
I end up with the executable crashing.
Thanks in advance, any advice would be appreciated.
-
jogojapan almost 11 yearsCould you show a complete (but minimal) example of the code that causes your process to crash?
basePointer.get()
alone certainly isn't a problem. -
Lukas Schmit almost 11 years@jogojapan I fixed my problem. I was doing some really weird casting with at least 5 sets of parenthesis. I'm pretty sure it was just something stupid, but I already changed it and don't remember what I did. Captain Obvlious' answer worked for me though. Thanks for all your help!
-
-
Marc over 7 yearsAre you sure there's no memory leak when you do basePointer.release()?
-
Captain Obvlious over 7 years@Marc Yes, I'm sure.
-
meneldal over 6 years@Marc The reason it is safe is because both
release()
andreset()
arenoexcept
, so unless you are doing something very bad outside this function, the raw pointer will always end up in the derived pointer and will be correctly destroyed. -
Masadow over 5 yearsIt might be obvious for some but please note that you are stealing the resource from the
basePointer
which is not always what you want in your unique_ptr conversion -
Daniel McLaury over 4 years@Masadow: If it's not what you want, then you don't want a unique pointer.
-
Charles Gueunet over 3 yearscan't we just use a std::move instead of cast + release ?
-
Johan Boulé over 3 yearsProblem with the answer. Yes, static_cast does also support polymorphic types. You should only use dynamic_cast when you're unsure whether the cast will work or fail (and in this case, test whether it returned null as you did).