为了学习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;家长。对于没有父节点的根节点,原始指针更容易。
答案 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();
}