So I am pretty new to C++ and I'm trying to combine std::unique_ptr
with a named constructor returning a std::optional
. I've got the following structure:
class AbstractClass {
public:
virtual ~AbstractClass() {}
};
class ChildClassA : public AbstractClass {
public:
static std::optional<ChildClassA> construct(...) { ... }
private:
ChildClassA(...) : ...{...} { ... }
};
std::unique_ptr<AbstractClass> construct(...) {
if (...) {
return std::make_unique<ChildClassA>(...); // call ChildClassA::construct(...) here
} else {
return std::make_unique<ChildClassB>(...); // call ChildClassB::construct(...) here
}
}
I want to have a function construct()
that calls the constructor of one of the child classes depending on some value. The constructors of these child classes may fail, thus I am using named constructors returning an std::optional
as described here. construct()
should return a std::unique_ptr
to make passing of ownership explicit and prevent copying of the constructed object.
Is this possible?
If your classes are movable then you can move them into the unique_ptr
:
#include <optional>
#include <memory>
class AbstractClass {
public:
virtual ~AbstractClass() {}
};
class ChildClassA : public AbstractClass {
public:
static std::optional<ChildClassA> construct();
private:
ChildClassA(){}
};
class ChildClassB : public AbstractClass {
public:
static std::optional<ChildClassB> construct();
private:
ChildClassB(){}
};
std::unique_ptr<AbstractClass> construct(bool a) {
if (a) {
auto temp = ChildClassA::construct();
if (temp) {
return std::make_unique<ChildClassA>(std::move(*temp));
}
return {};
} else {
auto temp = ChildClassB::construct();
if (temp) {
return std::make_unique<ChildClassB>(std::move(*temp));
}
return {};
}
}
However a possibly null unique_ptr
would be much simpler for this usecase:
#include <optional>
#include <memory>
class AbstractClass {
public:
virtual ~AbstractClass() {}
};
class ChildClassA : public AbstractClass {
public:
static std::unique_ptr<ChildClassA> construct();
private:
ChildClassA(){}
};
class ChildClassB : public AbstractClass {
public:
static std::unique_ptr<ChildClassB> construct();
private:
ChildClassB(){}
};
std::unique_ptr<AbstractClass> construct(bool a) {
if (a) {
return ChildClassA::construct();
} else {
return ChildClassB::construct();
}
}