组合 std::unique_ptr 和命名构造函数

Combining std::unique_ptr and named constructors

所以我是 C++ 的新手,我正在尝试将 std::unique_ptr 与命名构造函数 return 结合起来 std::optional。我有以下结构:

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
    }
}

我想要一个函数 construct(),它根据某个值调用其中一个子 类 的构造函数。这些子 类 的构造函数可能会失败,因此我使用命名构造函数 returning 一个 std::optional,如 here 所述。 construct() 应该 return 一个 std::unique_ptr 以明确传递所有权并防止复制构造的对象。

这可能吗?

如果您的 类 是可移动的,那么您可以将它们移动到 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 {};
    }
}

然而,对于此用例,可能为 null unique_ptr 会简单得多:

#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();
    }
}