Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/149.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
课堂上独特的\u ptr如何与他们合作 我在C++中实现AVL树,使用 UNQuyGyPTR < /代码>为儿童。< /P> struct Node { const int key; std::unique_ptr<Node> left, right; Node* parent; std::size_t height; ///< for avl tree. Node(const int key) : key(key), height(0) {} }; class AVL { std::unique_ptr<Node> root; public: AVL(int rootKey) : root(std::unique_ptr<Node>(new Node(rootKey))) { } void insert(std::unique_ptr<Node> newNode) { std::unique_ptr<Node> & node = root; Node* parentWeak; while(node.get()) { parentWeak = node->parent; if (node->key == newNode->key) throw std::runtime_error("Key already present"); if (node->key < newNode->key) node = node->right; else node = node->left; } auto parent = parentWeak; const int key = newNode->key; if (parent == nullptr) { // there is no root root = std::move(newNode); } else { if (parent->key < newNode->key) { assert(NULL == parent->right.get()); parent->right = std::move(newNode); } else { assert(NULL == parent->left.get()); parent->left = std::move(newNode); } } // Now increment the height upto down. incrementHeight(key); // balance starting from parent upwards untill we find some dislanace in height balance(parent, key); } }; struct节点 { 常量int键; std::唯一的左、右ptr; 节点*父节点; 标准::avl树的大小和高度;//父节点; 如果(节点->键==新节点->键) 抛出std::runtime_错误(“密钥已存在”); 如果(节点->键键) 节点=节点->右侧; 其他的 节点=节点->左; } 自动父项=父项弱; const int key=newNode->key; 如果(父项==nullptr){ //没有根 root=std::move(newNode); }否则{ if(父级->键键){ 断言(NULL==parent->right.get()); 父->右=标准::移动(新节点); }否则{ 断言(NULL==parent->left.get()); 父->左=标准::移动(新节点); } } //现在,将高度增加到“向下”。 增加高度(键); //从母体开始向上平衡,直到我们发现高度不一致 余额(父项、键); } };_C++_C++11_Shared Ptr_Unique Ptr - Fatal编程技术网 键==新节点->键) 抛出std::runtime_错误(“密钥已存在”); 如果(节点->键键) 节点=节点->右侧; 其他的 节点=节点->左; } 自动父项=父项弱; const int key=newNode->key; 如果(父项==nullptr){ //没有根 root=std::move(newNode); }否则{ if(父级->键键){ 断言(NULL==parent->right.get()); 父->右=标准::移动(新节点); }否则{ 断言(NULL==parent->left.get()); 父->左=标准::移动(新节点); } } //现在,将高度增加到“向下”。 增加高度(键); //从母体开始向上平衡,直到我们发现高度不一致 余额(父项、键); } };,c++,c++11,shared-ptr,unique-ptr,C++,C++11,Shared Ptr,Unique Ptr" /> 键==新节点->键) 抛出std::runtime_错误(“密钥已存在”); 如果(节点->键键) 节点=节点->右侧; 其他的 节点=节点->左; } 自动父项=父项弱; const int key=newNode->key; 如果(父项==nullptr){ //没有根 root=std::move(newNode); }否则{ if(父级->键键){ 断言(NULL==parent->right.get()); 父->右=标准::移动(新节点); }否则{ 断言(NULL==parent->left.get()); 父->左=标准::移动(新节点); } } //现在,将高度增加到“向下”。 增加高度(键); //从母体开始向上平衡,直到我们发现高度不一致 余额(父项、键); } };,c++,c++11,shared-ptr,unique-ptr,C++,C++11,Shared Ptr,Unique Ptr" />

课堂上独特的\u ptr如何与他们合作 我在C++中实现AVL树,使用 UNQuyGyPTR < /代码>为儿童。< /P> struct Node { const int key; std::unique_ptr<Node> left, right; Node* parent; std::size_t height; ///< for avl tree. Node(const int key) : key(key), height(0) {} }; class AVL { std::unique_ptr<Node> root; public: AVL(int rootKey) : root(std::unique_ptr<Node>(new Node(rootKey))) { } void insert(std::unique_ptr<Node> newNode) { std::unique_ptr<Node> & node = root; Node* parentWeak; while(node.get()) { parentWeak = node->parent; if (node->key == newNode->key) throw std::runtime_error("Key already present"); if (node->key < newNode->key) node = node->right; else node = node->left; } auto parent = parentWeak; const int key = newNode->key; if (parent == nullptr) { // there is no root root = std::move(newNode); } else { if (parent->key < newNode->key) { assert(NULL == parent->right.get()); parent->right = std::move(newNode); } else { assert(NULL == parent->left.get()); parent->left = std::move(newNode); } } // Now increment the height upto down. incrementHeight(key); // balance starting from parent upwards untill we find some dislanace in height balance(parent, key); } }; struct节点 { 常量int键; std::唯一的左、右ptr; 节点*父节点; 标准::avl树的大小和高度;//父节点; 如果(节点->键==新节点->键) 抛出std::runtime_错误(“密钥已存在”); 如果(节点->键键) 节点=节点->右侧; 其他的 节点=节点->左; } 自动父项=父项弱; const int key=newNode->key; 如果(父项==nullptr){ //没有根 root=std::move(newNode); }否则{ if(父级->键键){ 断言(NULL==parent->right.get()); 父->右=标准::移动(新节点); }否则{ 断言(NULL==parent->left.get()); 父->左=标准::移动(新节点); } } //现在,将高度增加到“向下”。 增加高度(键); //从母体开始向上平衡,直到我们发现高度不一致 余额(父项、键); } };

课堂上独特的\u ptr如何与他们合作 我在C++中实现AVL树,使用 UNQuyGyPTR < /代码>为儿童。< /P> struct Node { const int key; std::unique_ptr<Node> left, right; Node* parent; std::size_t height; ///< for avl tree. Node(const int key) : key(key), height(0) {} }; class AVL { std::unique_ptr<Node> root; public: AVL(int rootKey) : root(std::unique_ptr<Node>(new Node(rootKey))) { } void insert(std::unique_ptr<Node> newNode) { std::unique_ptr<Node> & node = root; Node* parentWeak; while(node.get()) { parentWeak = node->parent; if (node->key == newNode->key) throw std::runtime_error("Key already present"); if (node->key < newNode->key) node = node->right; else node = node->left; } auto parent = parentWeak; const int key = newNode->key; if (parent == nullptr) { // there is no root root = std::move(newNode); } else { if (parent->key < newNode->key) { assert(NULL == parent->right.get()); parent->right = std::move(newNode); } else { assert(NULL == parent->left.get()); parent->left = std::move(newNode); } } // Now increment the height upto down. incrementHeight(key); // balance starting from parent upwards untill we find some dislanace in height balance(parent, key); } }; struct节点 { 常量int键; std::唯一的左、右ptr; 节点*父节点; 标准::avl树的大小和高度;//父节点; 如果(节点->键==新节点->键) 抛出std::runtime_错误(“密钥已存在”); 如果(节点->键键) 节点=节点->右侧; 其他的 节点=节点->左; } 自动父项=父项弱; const int key=newNode->key; 如果(父项==nullptr){ //没有根 root=std::move(newNode); }否则{ if(父级->键键){ 断言(NULL==parent->right.get()); 父->右=标准::移动(新节点); }否则{ 断言(NULL==parent->left.get()); 父->左=标准::移动(新节点); } } //现在,将高度增加到“向下”。 增加高度(键); //从母体开始向上平衡,直到我们发现高度不一致 余额(父项、键); } };,c++,c++11,shared-ptr,unique-ptr,C++,C++11,Shared Ptr,Unique Ptr,我在第node=node->right行遇到编译器错误。这是正确的,因为只有std::move语义才能实现。但这是错误的,因为我只想在树上迭代,否则它只会将它们从子列表中删除 但是,我还需要unique\u ptr,因为它将在函数balance中传递,因为它将修改指针并重新平衡树 如果我使用shared\u ptr,一切都会正常。但是,我不需要与他人分享所有权。还是我误解了所有权?您的问题似乎是由于不了解如何在实际程序中使用与所有权概念相关的unique\u ptr。如果某个东西拥有一个对象,这

我在第
node=node->right行遇到编译器错误。这是正确的,因为只有
std::move
语义才能实现。但这是错误的,因为我只想在树上迭代,否则它只会将它们从子列表中删除

但是,我还需要
unique\u ptr
,因为它将在函数
balance
中传递,因为它将修改指针并重新平衡树


如果我使用
shared\u ptr
,一切都会正常。但是,我不需要与他人分享所有权。还是我误解了所有权?

您的问题似乎是由于不了解如何在实际程序中使用与所有权概念相关的
unique\u ptr
。如果某个东西拥有一个对象,这意味着,只要这个东西继续拥有这个对象,这个东西就有责任保持这个对象的生命,并且一旦没有任何东西拥有这个对象,这个东西就有责任销毁这个对象

unique_ptr
shared_ptr
都可以用于拥有对象。您似乎已经意识到,不同之处在于,
unique\u ptr
指向的对象只能有一个所有者,而可能有多个
shared\u ptr
对象共享特定对象的所有权。如果一个
unique\u ptr
被销毁或分配了不同的值,根据定义,它可以销毁它之前指向的对象,因为
unique\u ptr
是一个对象的单一(唯一)所有者

现在,您必须考虑您的树:您可以对所有内容使用
shared\u ptr
,这很可能(似乎)会起作用,因为只要存在对对象的引用,对象就会保持活动状态。如果
节点
中确实存在
成员,您在方法中使用该成员,但未在
节点
结构中声明该成员,则可能会创建引用循环,但这会造成将对象保留太长时间(甚至永远)的危险,这称为内存泄漏,在C++中,<>代码> SydRypPTR <代码>是纯引用计数。两个对象包含指向彼此的共享对象,即使没有其他指针指向它们,它们也会永远保持活动状态。似乎在您的
共享\u ptr
解决方案中,
父成员是
弱\u ptr
,这是解决此问题的合理方法,尽管可能不是最有效的方法

您似乎希望通过使用
unique\u ptr
而不是
shared\u ptr
来提高代码的性能和严格性,这通常被认为是一个非常好的想法,因为它迫使您更详细地处理所有权问题。您选择树拥有根节点,每个节点拥有子节点,这是一个合理的设计。您似乎已经删除了
父级
指针,因为它不能是
唯一的\u ptr
,在这种情况下,节点将由其父级及其可能拥有的任何子级拥有,违反了
唯一的\u ptr
指向的对象只能有一个所有者的约束。此外,
父级
成员不能是
弱ptr
,因为
弱ptr
只能用于由
共享ptr
管理的对象。如果你想把一个设计从“代码> SydDypPTR <代码>转换为<代码> UnQuyPPTR < /代码>,你应该考虑将<代码>弱小的PTR < /代码> s转换为原始指针。一个不包含指向由代码> > UNQuijpPTR <代码>管理的对象的指针,它检测出该对象的期满不存在(它不会用典型的C++内存管理有效地实现)。如果您需要能够检测到非所有者指针过时的属性,请继续使用
shared\u ptr
。跟踪非所有权指针的开销几乎与完全共享所有权语义一样大,因此在标准库中没有中间立场

最后,让我们讨论
insert
方法。
节点
变量肯定不是您想要的。您正确地发现(可能是通过编译器错误消息)节点不能是唯一的,因为这会剥夺树对象的所有权。事实上,让这个变量引用树中的根指针是正确的解决方案,因为您不想在这一点上混淆所有权,只想能够抓住