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

时间:2019-12-03 15:28:50

标签: c++ optional unique-ptr named-constructor

因此,我对C ++相当陌生,我正在尝试将std::unique_ptr与返回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(),该函数根据某个值调用子类之一的构造函数。这些子类的构造函数可能会失败,因此我正在使用命名构造函数,返回here中所述的std::optionalconstruct()应该返回std::unique_ptr,以明确所有权的传递并防止复制构造的对象。

这可能吗?

1 个答案:

答案 0 :(得分:2)

如果您的班级是可移动的,则可以将其移动到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 {};
    }
}

在这种情况下,可能为空的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();
    }
}