c++ - 使用指针的动态 LinkedList 的 push() 和 pop() 方法的 C++ 问题
问题描述
首先,我想在不使用 STL 的情况下创建一个带有指针的动态 LinkedList。这是一个了解指针如何在 C++ 中工作的练习。
我的问题是我的push()
方法没有像我期望的那样创建 FifoElement。当我运行程序时,在我使用该pop()
方法后它什么也没显示。我的一个例子main
如下。
要将push
新对象添加到列表中,我正在重载<<operator
并且要从列表中弹出第一个元素,我正在重载>>operator
我的两门课是Fifo
和FifoElement
先进先出:
template <class T>
class Fifo
{
public:
Fifo();
void push(const T&);
T pop();
Fifo& operator<<(const T&);
Fifo& operator>>(T&);
private:
FifoElement<T> *top;
};
先进先出元素:
template <class T>
class Fifo;
template<class T>
class FifoElement
{
friend class Fifo<T>;
public:
FifoElement();
private:
T value;
FifoElement<T> *next;
};
push 方法的代码片段:
...
template <class T>
void Fifo<T>::push(const T& val){
//creates new Element
FifoElement<T> *newElem = new FifoElement<T>(); //<= I think my problem is here but I am not sure..
//inserts new value into Element
newElem->value = val;
//If Fifo/List is empty: Element is top...
if(top == nullptr){
top = newElem; //...füge am Anfang ein
return;
}
//or:
//when List has elements go to the end and then insert element at the end
FifoElement<T> *tmpElem = top;
while(tmpElem->next != nullptr){
tmpElem = tmpElem->next;
cout << tmpElem << endl;
}
//set new Element as next of the last element in the list
tmpElem->next = newElem;
}
template <class T>
Fifo<T>& Fifo<T>::operator<<(const T& val){
push(val);
return *this;
}
...
和 pop() 方法部分:
...
template <class T>
T Fifo<T>::pop(){
//should read the first element of the list and delete it...
FifoElement<T> *tmpElem = nullptr;
FifoElement<T> *returnElem = nullptr;
//if top is empty it means that the list is empty...
if(top == nullptr){
cout << "Liste ist leer!" << endl;
returnElem = 0;
return returnElem->value;
}
//the new element is the new top
else if(top->next != nullptr){
top = top->next;
returnElem = tmpElem;
//hier wird Element gelöscht!
delete tmpElem;
tmpElem = nullptr;
//
return returnElem->value;
}
//if only top exists then return it and delete it after that
else{
delete top;
top = nullptr;
returnElem = tmpElem;
delete tmpElem;
tmpElem = nullptr;
return returnElem->value;
}
}
template <class T>
Fifo<T>& Fifo<T>::operator>>(T& val){
pop();
return *this;
}
...
我的主要例子是这样的:
...
int main() {
Fifo<string> test;
string ex = "Hey stackoverflow whatsup? :)";
string ex2 = "can anyone help me?";
test << ex;
test << ex2
test.pop(); //output here should be: "Hey, stackoverflow whatsup? :)"
test.pop(); //output here should be: "can anyone help me?"
...
return 0;
}
我希望我没有忘记任何事情。如果有人可以帮助我,那就太好了。我从 3 天开始就坐在那个程序上 :(
解决方案
您的pop
方法太复杂并且包含错误,尤其是在内存处理方面。做类似的事情
returnElem = tmpElem;
delete tmpElem;
是错误的,因为returnElem
您没有创建 的副本,FifoElement<T>
并且两个指针都指向同一个元素,因此只是变成了一个悬空指针。我把它改写为
template <class T>
T Fifo<T>::pop(){
T value;
if( top ){
auto const old = top;
top = top->next;
value = old->value;
delete old;
} else {
cerr << "error - queue empty";
}
return value;
}
通过该更改,您的示例代码可以正常工作。我没有检查它是否有其他错误。请参阅此处的工作示例
推荐阅读
- python - 在 3D 数组上映射 scipy percentileofscore
- python - 使用海龟进行布冯针模拟。我不能让我的 if else 语句来改变针的颜色?
- java - 2 个或更多用户尝试同时上传相同的数据
- cygwin - 有没有办法卸载 Cygwin B20?
- macos - 在 macOS Catalina、Big Sur 及更高版本中确定卷组
- java - 如何将 ByteArray 编码为 base36 字符串
- swift - 检查字符串是否等于实体中的对象属性
- amazon-s3 - 从亚马逊 s3 存储桶读取 csv 文件时更改列数据类型
- vb.net - 图片不会在图片框中更改,vb.net
- swiftui - SwiftUI状态变量封装最佳实践/复杂视图中状态变量过多