返回向量的unique_ptr指向值的副本

时间:2018-06-30 11:41:54

标签: c++ c++14

我正在尝试实现两种方法。我有一个像这样实现的节点类:

class Node
{
public:
    // A NodeMap is a std::map associating a node with its ID as a key, much faster for searching the Node than a simple vector
    using NodeMap = std::map<QString, std::unique_ptr<Node>>;

    Node();
    Node(const Vector3D &position);

    const Vector3D& getPosition() const;

    std::vector<Node*>& getLeaves() const;
    std::vector<Node>& getAbsoluteLeaves() const;

    bool hasChildren() const;

protected:
    Vector3D position_;
    NodeMap children_;
};

我已删除此问题的所有无用的内容。我的问题是方法getLeavesgetAbsoluteLeaves。第一个仅返回节点的叶子(没有任何子代的子代)。除了计算绝对位置外,第二个功能相同。我希望Node类保留子级的所有权。返回的向量仅用于查看节点值,不会更改。

这是我对第一种方法的实现

std::vector<Node*>& Node::getLeaves() const
{
    std::vector<Node*> leaves;

    for (const auto &child : children_) {
        if (child.second->hasChildren()) {
            std::vector<Node*> child_children(child.second->getLeaves());
            leaves.insert(leaves.end(), child_children.begin(), child_children.end());
        } else {
           leaves.push_back(child.second.get());
        }
    }

    return leaves;
}

我在这里返回一个指针向量,我读到这是一个好习惯。第一个问题,使用指针后是否需要手动删除指针?此方法使程序崩溃,没有任何消息,但可以编译。错误可能从何而来?我怎么找到它?

这是第二种方法的实现:

std::vector<Node>& Node::getAbsoluteLeaves() const
{
    std::vector<Node> leaves;

    for (auto child : children_) {
        if (child.second->hasChildren()) {
            std::vector<Node> child_children = child.second->getAbsoluteLeaves();
            leaves.insert(leaves.end(), child_children.begin(), child_children.end());
        } else {
            child.second->setPosition(child.second->getPosition() + position_); // Need to edit a copy of this node, not the original one!
            leaves.push_back(child.second.get());
        }
    }

    return leaves;
}

这个不编译,我知道为什么,我必须复制指向的节点才能计算绝对位置,但是我不能用unique_ptr来做。我应该如何解决这个问题?我真的不知道如何实现此方法。

1 个答案:

答案 0 :(得分:1)

对于第二个功能,您可以像这样复制并存储由unique_ptr引用的Node:

leaves.push_back(*child.second); // makes a copy
leaves.back().setPosition(child.second->getPosition() + position_);

当然,Node将需要具有副本构造函数。您的问题还不清楚,因为NodeMap是不可复制的(由于包含unique_ptrs)。