c++ - 为什么我的类节点会覆盖自己而不是创建新的节点对象
问题描述
有人可以运行此代码并告诉我为什么插入中的节点不断覆盖?
#ifndef LinkedList_hpp
#define LinkedList_hpp
#include <stdio.h>
#include <utility>
template<class T>class LinkedList{
public:
LinkedList(){
head = nullptr;
tail = nullptr;
size = 0;
}
//void insert(T val);
class Node{
public:
Node* next;
T* value;
Node* prev;
Node(T* value){
this->value = value;
}
Node(){
}
Node(T* value,Node* prev, Node* next){
this->value = value;
this->next = next;
this->prev = prev;
}
Node* operator=(const Node& node){
this->value = node.value;
this->prev = node.prev;
this->next = node.next;
return *this;
}
};
public:
Node* head;
Node* tail;
int size;
void insert(T val){
在这一行,如果前一个 head 是 10,则当前 val 40 会覆盖旧 head 值并插入一个 val 40 的新节点
Node* temp = new Node(&val);
if(head==nullptr){
head = temp;
tail = temp;
}else{
temp->next = head;
head->prev = temp;
head = temp;
}
size++;
}
#endif
#include <iostream>
#include "LinkedList.hpp"
int main(int argc, const char * argv[]) {
// LinkedList<int> t;
int h = 7;
int j = 10;
int k = 40;
LinkedList<int>* list1 = new LinkedList<int>();
list1->insert(h);
list1->insert(j);
list1->insert(k);
return 0;
}
每次调用 insert 并构造一个新节点时,它都会覆盖旧值,一切都成为当前 Val
解决方案
void insert(T val){
val
是这个函数的一个参数。此对象 thisval
仅在此函数返回之前存在。此时它会被销毁,就像在函数内的非静态范围内声明的所有其他内容一样。这就是 C++ 的工作原理。一旦insert()
回来,就val
不再这样了。它不复存在。它去见它的制造者。它变成了一个前对象,不再存在,完全成为过去。
您的insert()
函数执行以下操作:
Node* temp = new Node(&val);
您将指向此val
参数的指针传递给Node
的构造函数,Node
然后将指向参数的指针保存为insert()
,作为其自己的类成员。
这很好,但是一旦insert()
返回,new
-ed中保存的指针Node
就变成了一个指向被破坏对象的指针,并且取消引用这个指针变成了未定义的行为。
然后,您稍后会尝试取消引用原始指针,该指针不再指向有效对象。
这解释了您的代码中观察到的未定义行为。
底线是您的类和模板的设计存在根本缺陷。Node
使用指针没有明显的目的。Node
应该简单地存储T
为它自己的类成员,作为value
, 而不是value
指向其他T
存在于某处的指针,并且可以随时被销毁,这不受Node
's 的控制。
所示代码中的另一个问题是 的两个Node
构造函数未能初始化next
和指向 的prev
指针NULL
。这也会导致未定义的行为。
推荐阅读
- c++ - 带参数的方法 (const T *&) or (T * &) or(const T * const &) or(T * const &)
- asp.net - 添加新产品时覆盖会话数组列表
- css - CSS - 仅显示图像背景的左上部分
- python - 无法使用 webdriver 从 xpath 拆分一个单元格的表中获取数据
- hadoop-yarn - 为什么作业在启动时应用与默认并行度一样多的 TM
- node.js - 命令:heroku 登录正在生成错误
- oculusgo - 如何在 oculus go 中录制视频和截屏时设置特定的宽度和高度
- java - 将字符串添加到 ArrayList 但仍然看到大小为 0
- ruby-on-rails - Elasticsearch Rails 批量索引
- google-api - Gmail API 在发送电子邮件时覆盖自定义 Message-ID 标头