Home > Software design >  Initialise unique_ptr inside class
Initialise unique_ptr inside class

Time:10-23

I want to initialise the unique pointer inside class after declaration and I tried few ways but unable to resolve the errors..

template <typename T>
struct Destroy
{
    void operator()(T *t) const
    {
        t->destroy();
    }
};

class Test
{
    
    std::unique_ptr<IRuntime, Destroy<IRuntime>> runtime;

public:
    Test()
    {
        /*
        the function createIRuntime() return type is *IRuntime.
        I tried using following but all the ways I got error:
        1. runtime = std::make_unique<IRuntime, Destroy<IRuntime>> (createIRuntime());  
        2. runtime = createIRuntime();  
        3. runtime = std::unique_ptr<IRuntime, Destroy<IRuntime>> (createIRuntime());        
               
                 Works fine if I do follow.
                 std::unique_ptr<IRuntime, Destroy<IRuntime>> runtime(createIRuntime());
        */
        
        /* how to initialize the unique pointer here*/
    }
};

CodePudding user response:

runtime = std::make_unique<IRuntime, Destroy<IRuntime>> (createIRuntime());

Presumably IRuntime is an abstract class, which can't be constructed directly.

But even if it could be constructed as-is, only the 1st template parameter specifies the type to create. The 2nd and subsequent template parameters specify the types of parameters for the constructor that is called.

So, this statement is trying to call an IRuntime constructor that takes a Destroy<IRuntime> object as a parameter, passing a raw IRuntime* pointer to that parameter. No such constructor exists, so this fails to compile.

runtime = createIRuntime();

std::unique_ptr does not have an operator= that takes a raw pointer, only a std::unique_ptr. std::unique_ptr has a constructor that takes a raw pointer, but that constructor is marked explicit. So this fails to compile, too.

runtime = std::unique_ptr<IRuntime, Destroy<IRuntime>> (createIRuntime());

This is correct, and works just fine:

Online Demo

Another statement that works is:

runtime.reset(createIRuntime());

Online Demo

Also, since the code you showed is inside of another constructor, you can (and should) use that constructor's member initialization list:

Test() : runtime(createIRuntime())
{
}

Online Demo

  • Related