【问题标题】:Combining std::unique_ptr and named constructors结合 std::unique_ptr 和命名构造函数
【发布时间】:2019-12-03 15:28:50
【问题描述】:

所以我对 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(),它根据某个值调用其中一个子类的构造函数。这些子类的构造函数可能会失败,因此我使用命名构造函数返回std::optional,如here 所述。 construct() 应返回 std::unique_ptr 以明确传递所有权并防止复制构造的对象。

这可能吗?

【问题讨论】:

  • 仅当您的子类可移动时
  • 更改工厂函数以返回 null unique_ptrs 而不是 std::optional 会简单得多

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


【解决方案1】:

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

【讨论】:

  • 我会将optional -> unique_ptr 提取到它自己的函数中(可能带有Args&amp;&amp; ... args + 转发咒语)以改进这个答案(例如godbolt.org/z/Y2xcF7),但总的来说这个也是我在这些限制下推荐的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-20
  • 1970-01-01
  • 1970-01-01
  • 2021-08-28
  • 1970-01-01
  • 2022-12-04
相关资源
最近更新 更多