If I need polymorphism should I use raw pointers instead of unique_ptr
?
I saw some threads that show how to use unique_ptr
for polymorphic behaviour.
I am not sure it is worth the trouble, I would rather stay with raw pointers.
Can you please comment on this, your opinion on raw vs smart pointers in this context?
You need pointers or reference because for the kind of polymorphism you are interested in (*), you need that the dynamic type could be different from the static type, in other words that the true type of the object is different than the declared type. In C++ that happens only with pointers or references.
The rule would be this - if you know that an entity must take a certain kind of ownership of the object, always use smart pointers - the one that gives you the kind of ownership you need. If there is no notion of ownership, never use smart pointers.
Use unique_ptr when you want a single pointer to an object that will be reclaimed when that single pointer is destroyed. Use shared_ptr when you want multiple pointers to the same resource.
When to use unique_ptr? Use unique_ptr when you want to have single ownership(Exclusive) of the resource. Only one unique_ptr can point to one resource. Since there can be one unique_ptr for single resource its not possible to copy one unique_ptr to another.
The following simple code shows that std::unique_ptr
works just fine from a polymorphism point of view, printing "Hello from Derived."
.
#include <iostream>
#include <memory>
using std::cout;
struct Base
{
virtual ~Base() { }
virtual void SayHello()
{
cout << "Hello from Base.\n";
}
};
struct Derived : public Base
{
void SayHello() override
{
cout << "Hello from Derived.\n";
}
};
int main()
{
std::unique_ptr<Base> pBase( new Derived() );
// Or using std::make_unique:
//
// std::unique_ptr<Base> pBase = std::make_unique<Derived>();
pBase->SayHello();
}
Anyway, observing raw pointers are fine; what you must pay attention to are owning raw pointers. Owning raw pointers should be safely wrapped inside RAII boundaries (using unique_ptr
, shared_ptr
, or some custom resource manager).
Use unique_ptr
to control ownership of allocated resources, e.g. allocate on the free store inside a function and return a unique_ptr
.
Use just a reference for polymorphic behavior if ownership is not an issue. Even if a unique_ptr
does the same, you spare the compiler from additional work.
Use a pointer for polymorphic behavior within a container if ownership is not an issue. You cannot have a container of references.
Smart pointers are about ownership/lifetime. Where you need to manage the lifetime of a polymorphic object, use a smart pointer. If you are just using the object, prefer raw references/pointers (in that order) over smart pointers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With