Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If I need polymorphism should I use raw pointers instead of unique_ptr?

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?

like image 646
user3111311 Avatar asked Feb 28 '14 22:02

user3111311


People also ask

Do you need pointers for polymorphism?

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.

In what kind of circumstances would you use a raw pointer instead of a smart pointer?

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.

Should I use unique_ptr or shared_ptr?

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 should we use unique_ptr?

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.


3 Answers

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).

like image 68
Mr.C64 Avatar answered Oct 05 '22 12:10

Mr.C64


  • 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.

like image 35
iavr Avatar answered Oct 05 '22 10:10

iavr


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.

like image 35
Nevin Avatar answered Oct 05 '22 11:10

Nevin