C ++将unqiue_ptr与同一对象

时间:2016-03-04 14:37:59

标签: c++

为了学习c ++,我一直在用算法练习一些练习。我正在编写一个单词trie,并考虑将unique_ptr与同一对象的原始指针混合的解决方案。我观看了演讲者正在讨论的讲座,以免过度使用unique_ptr和shared_ptr。他们还提到原始指针是好的,只要没有所有权暗示。我确信这可以用另一种方式实现,但我想了解是否存在我没​​有看到的问题。据我所知,这是一种常见的做法,或者你能做的最蠢的事情。这是一堂课。

class node {
public:
    node(node * parent) :
        parent { parent } {
    }

    void insert(const std::string & word, int index) {
        auto c = word[0];
        if (children[c-'a'] == nullptr) {
            children[c-'a'] = std::make_unique(this);
        }

        if(!word.size()>1) {
            children[c-'a']->tnsert(word.substr(1), index);
        }
        else {
            occurrences.push_back(index);
        }
    }

    std::unique_ptr<node> & find(const std::string & word) const {
        auto c = word[0];
        if (children[c-'a'] != nullptr) {
            if(!word.size()>1) {
                return children[c-'a']->find(word.substr(1);
            }
            else {
                return children[c-'a'];
            }
        }
        return nullptr;
    }

private:
    node * parent;
    std::vector<std::unique_ptr<node>> children(26);
};

我选择将向量中的节点作为unique_ptrs保存,原因有二,内存和空槽在算法中具有重要意义。在创建子项时的insert方法中,我在其构造函数中使用了this。我甚至认为find方法可以用原始指针实现:

 node * find(const std::string & word) const;

我只需要添加一个像node * get_raw()这样的成员{return this;而不是返回子项作为unique_ptr只返回get_raw();.我知道有很多方法可以对此进行不同的编码。我本可以使用std :: unique_ptr&amp;家长。对于没有父节点的根节点,原始指针更容易。

1 个答案:

答案 0 :(得分:0)

您的vector unique_ptrs是合法的,有一个好处是您可以致电children.clear(),并且每个指针都会被正确删除。

如果要修改unique_ptr& or unique_ptr*对象,则只应返回unique_ptr

返回unique_ptr对于使用get()返回原始指针没有任何好处,因为在一天结束时,您需要test nullptr在这两种情况下。

此外,您的查找功能未正确写入:

std::unique_ptr<node> & find(const std::string & word) const {
    auto c = word[0];
    if (children[c-'a'] != nullptr) {
        if(!word.size()>1) {
            return children[c-'a']->find(word.substr(1);
        }
        else {
            return children[c-'a'];
        }
    }

    // nullptr will be converted to a local unique_ptr object. you cannot
    // return a reference to a local object that's about to be destroyed.
    // return nullptr;

    static const std::unique_ptr<node> empty;
    return empty;
}

// Or
node* find(const std::string & word) const 
{
    return children[c-'a'].get();
}