将unique_ptr分配给原始指针

Assigning a unique_ptr to a raw pointer

本文关键字:原始 指针 分配 ptr unique      更新时间:2023-10-16

我正在尝试使用唯一的指针将一个节点链接到另一个节点。我设法用下面的代码做到了,但它感觉像是糟糕的代码,因为它太长了.我怎样才能改善这一点?

#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();
}

简短的评论是,您不应该传达来自其他 palces 的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来正确转让所有权。