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
.
source to share
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
source to share
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.
source to share
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);
}
source to share