更改unique_ptr指向的指针是否是未定义的行为?

时间:2019-07-03 20:23:57

标签: c++ pointers unique-ptr

对通过get()获得的unique_ptr原始指针执行reset()是未定义的行为,就像:

   std::unique_ptr<int> thing(new int(8));
   int* other = thing.get();
   other.reset(new int(15));

但是,如果unique_ptr的原始指针可以指向相同类型的对象怎么办?例如给出以下代码

class Node {
    public:
        std::unique_ptr<Node> previous;
        std::unique_ptr<Node> next;
        int data;        
        Node(int d) : previous(nullptr),
                      next(nullptr),   
                      data(d) {}
};

void some_function(std::unique_ptr<Node> node, Node* other_ptr) {
    Node* node_ptr = node.get();
    node_ptr->next.reset(other_ptr); // ***           
    ………………………………………………………………………………….
    ………………………………………………………………………………….
   // Some code. Please don't focus on the secondary things.
   // The main question whether it allowed to perform reset from line ****)
}

这也是未定义的行为吗?如果是,为什么。

代码链接:Code

1 个答案:

答案 0 :(得分:2)

在以下前提条件下,some_function的行为得到了很好的定义:

  • other_ptr必须已经使用new进行了分配,并且仍然有效(未删除)。
  • other_ptr的所有权必须已经转移 1 到该函数,即没有其他所有权。
  • node不能为空。

但是,node与所有参数一样,是函数的局部变量。函数结束时,node被销毁。因此,它管理的指针将被删除。因此,修改指向的对象似乎是毫无意义的,这就是函数的作用。

1 使用裸指针转移所有权是一个坏主意。相反,您应该使用唯一的指针来转移所有权。


P.S。使用nextprevious指针,Node看起来很像一个双向链接列表。但是,它不能是列表,因为上一个节点和下一个节点可能都不能对当前节点拥有唯一的所有权。

P.P.S。 Node* node_ptr = node.get(); node_ptr->next.reset...可以简化为node->next.reset