[英]How to correctly use smart pointers inside of a class
我在 C++ 中創建二叉樹,在節點 class 內部使用智能指針時遇到一些問題。 使用普通指針時,一切正常,但使用智能指針時,它就無法正常工作。 我認為問題出在插入方法中的這一行:
'''
binaryNode* node = this; // This is working
std::shared_ptr<binaryNode> node {this}; // This throws "double free or corruption" error
std::shared_ptr<binaryNode> node = shared_from_this (); // This throws "bad weak ptr error", I am correctly inheriting from enable_shared_from_this
'''
如何復制binaryNode* node = this;
用智能指針? 我什至嘗試成功地使用public std::enable_shared_from_this<binaryNode>
。 謝謝你的幫助!
編輯:我會嘗試更好地解釋自己。 這是二叉搜索樹的insert()
function,如下所示(這是 .cpp 文件):
'''
#include "binarynode.h"
binaryNode::binaryNode(int value){
this->value = value;
this->right = nullptr;
this->left = nullptr;
}
void binaryNode::insert(int value){
binaryNode* node = this;
while(true){
if(value > node->value){
if(node->right != nullptr){
node = node->right;
}else{
node->right = new binaryNode(value);
break;
}
}else if(value < node->value){
if(node->left != nullptr){
node = node->left;
}else{
node->left = new binaryNode(value);
break;
}
}else{
return;
}
}
如何使用智能指針復制它?
編輯 2:這是 my.h 文件:
'''
#ifndef BINARYNODE_H
#define BINARYNODE_H
class binaryNode
{
public:
int value;
binaryNode(int value);
binaryNode* right;
binaryNode* left;
void insert(int value);
};
#endif // BINARYNODE_H
這是主文件:
#include <iostream>
#include "binarynode.h"
using namespace std;
void printTree(binaryNode* node){
if(node == nullptr) return;
cout << node->value << endl;
printTree(node->left);
printTree(node->right);
}
int main(){
binaryNode* bn = new binaryNode(9);
bn->insert(4);
bn->insert(20);
bn->insert(1);
bn->insert(6);
bn->insert(15);
bn->insert(170);
printTree(bn);
return 0;
}
std::shared_ptr<binaryNode> node {this}
給你一個雙重刪除。shared_from_this
除非至少有一個共享指針已經指向你的 object。 這就是std::shared_ptr<binaryNode> node = shared_from_this ()
不起作用的原因。如果您想要共享指針,請將它們全部共享。 例如:
// binaryNode* bn = new binaryNode(9); <-- nope!
auto bn = std::make_shared<binaryNode>(9);
// binaryNode* node = this; <-- nope!
std::shared_ptr<binaryNode> node = shared_from_this();
我不建議在這里使用共享指針。 唯一指針更合適。
您不需要使用 shared_ptr<>。
實際上,智能指針在這里“解決” object 的所有權,因此當 object 有一個所有者時,應該使用 unique_ptr<>,當所有權共享時,使用 shared_ptr。 在你的情況下,所有權是明確的,每個節點都擁有它的左右成員,因此可以使用 unique_ptr 。
對於樹遍歷問題,不要弄亂智能指針,因為您不請求任何所有權,而只是查看值,因此原始指針是可以的。
所以你最終可能會得到這樣的結果:
#include <memory>
#include <iostream>
struct binaryNode {
binaryNode(int value) : value(value) {}
void insert(int value);
int value = 0;
std::unique_ptr<binaryNode> right;
std::unique_ptr<binaryNode> left;
};
void binaryNode::insert(int value){
binaryNode* node = this;
while(true){
if(value > node->value){
if(node->right != nullptr){
node = node->right.get();
}else{
node->right = std::make_unique<binaryNode>(value);
break;
}
}else if(value < node->value){
if(node->left != nullptr){
node = node->left.get();
}else{
node->left = std::make_unique<binaryNode>(value);
break;
}
}else{
return;
}
}
}
void printTree(const binaryNode &node){
std::cout << node.value << std::endl;
if (node.left)
printTree(*node.left);
if (node.right)
printTree(*node.right);
}
int main(){
auto bn = std::make_unique<binaryNode>(9);
bn->insert(4);
bn->insert(20);
bn->insert(1);
bn->insert(6);
bn->insert(15);
bn->insert(170);
printTree(*bn);
return 0;
}
您可能會注意到 print 不需要使用指針,它可以在引用上工作。
C++ 向量可用於支持遞歸數據結構。 使用 smart ptr 要簡單得多。 基本上在您的節點中存儲向量子項作為成員。
#include <vector>
using std::vector;
struct Node {
Node() = default;
Node(const Node &) = delete;
Node(Node &&) = default;
vector<Node> children;
};
int main()
{
Node root;
root.children.push_back(Node());
root.children.push_back(Node());
root.children[0].children.push_back(Node());
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.