How to create an object with a unique element?

I have a base class:

class Base {
public:
    Base(??? new_p) : p(new_p) {} 
    std::unique_ptr<MyType> p;
}

      

And the derived class:

class Derived : public Base {
    Derived(??? new_p) : Base(new_p) {}
}

      

What type of question marks replace if I want to build Derived

? Other changes are fine too. I want to make sure it is Derived

possible to build without copying MyType

that points to p

.

+3


source to share


3 answers


Depends on what you want to support - one or both of the below constructors make sense: from MyType*

or std::unique_ptr<MyType>&&

, which requires the caller to call the movable unique_ptr

. Just using std::unique_ptr<MyType>

it works too, because it std::unique_ptr

has a constructor from other relocatable instances ... it's just a matter of whether you want to emphasize the inevitably temporary nature of the inbound unique_ptr

in your own code.

class Base
{
  public:
    Base(MyType* new_p) : p(new_p) { } 
    Base(std::unique_ptr<MyType>&& new_p) : p(std::move(new_p)) { } 

    std::unique_ptr<MyType> p;
};

class Derived : public Base
{
  public:
    Derived(MyType* new_p) : Base(new_p) { }
    Derived(std::unique_ptr<MyType>&& new_p) : Base(std::move(new_p)) { }
};

      



See how it works here

+1


source


I would replace ???

on std::unique_ptr<MyType>

, and then std::move

in the mem-initializer.

class Base {
public:
    Base(std::unique_ptr<MyType> new_p) : p(std::move(new_p)) {} 
    std::unique_ptr<MyType> p;
};

class Derived : public Base {
    Derived(std::unique_ptr<MyType> new_p) : Base(std::move(new_p)) {}
};

      



You can also use std::unique_ptr<MyType>&&

instead of std::unique_ptr<MyType>

and avoid std::move

, but I prefer the by value approach for the reasons given in this answer ..

I would recommend not accepting an argument MyType *

. The problem with this solution is that it doesn't convey to the user your intention to take responsibility for the pointer passed to the constructor.

+1


source


This worked for me. Edit to note that I'm using a string as a type, only to make it easier to read, you should replace it with your type.

#include <memory>
#include <string>
#include <iostream>
#include <utility>

class Base {
public:
    Base(std::unique_ptr<std::string> new_p) 
      : p(std::move(new_p)) {} 
    std::unique_ptr<std::string> p;
};

class Derived : public Base {
public:
    Derived(std::unique_ptr<std::string> new_p) 
      : Base(std::move(new_p)) {}
};

int main(){
    std::unique_ptr<std::string> text(new std::string("Hello world"));

    Derived a(std::move(text));

    std::cout << *(a.p);
}

      

0


source







All Articles