C++将unqiue_ptr与同一对象的原始指针混合在一起

C++ mixing unqiue_ptr with raw pointer for the same object

本文关键字:对象 原始 指针 在一起 混合 unqiue ptr C++      更新时间:2023-10-16

我一直在用算法练习一些练习来学习 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,原因有两个 内存和空插槽在算法中具有重要意义。在创建子项时的插入方法中,我在其构造函数中使用了this。我什至认为 find 方法可以使用原始指针实现,例如:

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

我只需要添加一个像节点 * get_raw() { 返回这个; } 这样的成员,而不是像unique_ptr那样返回孩子,只需返回 get_raw();。我知道有很多方法可以以不同的方式编码。我本可以使用std::unique_ptr和parent。原始指针对于没有父节点的根节点来说更容易。

你的unique_ptrs vector是合法的,一个好处是你可以调用children.clear(),,每个指针都会被正确删除。

仅当要修改unique_ptr对象时,才应返回unique_ptr& or unique_ptr*

与使用 get() 返回原始指针相比,返回unique_ptr没有任何好处,因为在一天结束时,您需要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();
}