将 unique_ptr 分配给原始指针

Assigning a unique_ptr to a raw pointer

我正在尝试 link 使用唯一指针将一个节点连接到另一个节点。我设法用下面的代码做到了,但它感觉像糟糕的代码,因为它太啰嗦了。我该如何改进?

#include <memory>
#include <iostream>

using namespace std;

template<typename T>
class Node {
public:
    T data;    
    unique_ptr<Node<T>> nextNode;

    Node(T dataIn) : data(dataIn), nextNode(nullptr) {                   
    }

    void setNextNode(Node<T> * nodeIn) {          
      unique_ptr<Node<T>> newNextNode(nodeIn);
      nextNode = std::move(newNextNode);                 
    }   

    void printData() {
      cout << data << endl;
    }
};

int main() {      
  unique_ptr<Node<int>> root(new Node<int>(26));    
  Node<int> * nodeTwo = new Node<int>(88);      
  root->setNextNode(nodeTwo);   
}

也许使用移动的右值引用和交换:

#include <memory>
#include <iostream>

using namespace std;

template<typename T>
class Node {


public:
    T data;
    unique_ptr<Node<T>> nextNode;

    Node(T dataIn) : data(dataIn), nextNode(nullptr) {

    }

    void setNextNode(std::unique_ptr<Node<T>> &&nodeIn) {
            std::swap(nextNode, nodeIn);
    }

    void printData() {
      cout << data << endl;
    }



};




int main() {
  unique_ptr<Node<int>> root(new Node<int>(26));
  root->setNextNode(std::make_unique<Node<int>>(88));
  root->nextNode->printData();

}

简短的评论是你不应该从其他地方传达 unique_ptrs 作为它的全部点来显示所有权,所以这就是说改变 setNextNode:

void setNextNode(T &&nodeValue) {
        nextNode = std::make_unique<Node<T>>(nodeValue);
}

然后像这样添加:

root->setNextNode(88);

此外 make_unique 是 c++14 的一部分,如果您使用的是 c++11,请使用 reset:

nextNode.reset(new Node<T>(nodeValue));

这不是使用 unique_ptrs 的推荐方式:您可以使用 std::make_unique 而不是使用 new 创建对象,它会自动将对象包装在一个唯一的指针中.

您还混合了原始指针和唯一指针,这很糟糕,因为它会导致混淆谁是所传递对象的所有者。以下是更好列表的示例:

#include <memory>
#include <iostream>

template<typename T>
class Node {
public:
    T data;
    std::unique_ptr<Node<T>> nextNode = nullptr;

    Node(T dataIn) : data(dataIn) {

    }

    void setNextNode(std::unique_ptr<Node<T>>&& nodeIn) {
      std::swap(nextNode, nodeIn);
    }

    void printData() {
      std::cout << data << std::endl;
    }
};




int main() {
  auto root = std::make_unique<Node<int>>(26);
  auto nodeTwo = std::make_unique<Node<int>>(88);
  root->setNextNode(std::move(nodeTwo));

}

请注意使用 std::movestd::swap 来正确转让所有权。