2015-05-21 50 views
0

我使用unique_ptr与正常指针混合实现了一个单链表。是否正在给一个unique_ptr指定一个正常指针?

我有这样的代码:

template<typename B> 
void linkedlist<B>::addNode(B x){ 
    node * n = new node;      //initialize new node 
    n->x = x; 
    n->next = nullptr;      //smart pointer 

    if(head == nullptr){      //if the list is empty 
    head = (unique_ptr<node>)n;    //cast the normal pointer to a unique pointer 

    }else{         //if there is an existing link 
    current = head.get();     //get the address that is being 
              //pointed by the unique_ptr head 


    while(current->next != nullptr)   //loop until the end then stop 
     current = (current->next).get(); 

    current->next = (unique_ptr<node>) n; //connect the new node to the last node 
    } 
} 

我听说,这是一个不好的做法,如果是的话那么谁能告诉我,为什么?建议和正确的做法提示也将不胜感激。

+3

直接使用'auto n = std :: make_unique ();'和'head = std :: move(n);'以避免所有的投射。 – Jarod42

+0

我明白了,让我试试看。 –

+4

为什么你的缩进如此混乱?什么阻止你纠正这一点? –

回答

5

虽然投语法有点陌生,这是完全等同于更传统的

unique_ptr<node>(n) 

,因此本身并不是不好的做法。不好的做法是让原始指针悬而未决,如果存在不删除它或将其转移到智能指针的代码路径,则可能会泄漏原始指针。

你应该

unique_ptr<node> n(new node); 

开始,通过从移动

head = std::move(n); 
+0

所以我将不得不改变节点* n =新节点; unique_ptr n(新节点);? –

+2

@CarloBrew:你应该,是的。然后你可以确定它不会泄漏,而不必跟踪所有的代码路径来确保。 –

+0

我将所有内容都转换为您所说的内容,并且仍然按照预期工作。感谢您的答复和澄清! –

0

在你的情况下,它可能不是一个问题,但铸造现有的原始指针unique_ptrs转移所有权是一个有点不好的做法主要是由于涉及的语义。当超出范围时,Unique_ptr将运行删除器。

考虑以下

int ptr_method(int * i) { 
    auto a = (unique_ptr<int>)i; 
    return *a.get(); 
} 

int main() { 
    int i = 10; 
    ptr_method(&i); 
} 

恰好iptr_method的回报是什么?

+0

这不是重点。 –

+1

@LightnessRacesinOrbit在这个问题中,不,它更像是将原始指针投射到unique_ptr的做法的评论。 –

+0

我试过你的代码,我打印它,它仍然显示为10. –

相关问题