我为队列创建了一个类,我在循环中使用该类的对象。在迭代之后,队列中第一个元素的值变为残值。为什么这样,我该如何解决? 这是.h文件:
#ifndef QUEUE_H
#define QUEUE_H
#include "headers.h"
template <class T>
class Queue
{
public:
Queue();
~Queue();
void Push(T value); // Insert a new element at the end of the queue.
void Display(); // Display the queue.
T Pop(); // Delete the top of the queue and returns it.
T Peek(); // Returns the top of the queue.
T GetPositionValue(uint pos); // Returns the value found on the specified position.
T GetMin(); // Returns the lowest value in the queue.
T GetMax(); // Returns the highest value in the queue.
uint Distance(T value); // Returns -1 if the value isn't in the queue, else returns the distance from the top.
uint GetSize() const { return size; } // Returns the number of elements found in the stack.
bool IsEmpty() { return (first == nullptr); } // Returns true if the queue is empty.
bool HasValue(T value); // Returns true if the value is in the queue.
bool HasPosition(uint pos); // Returns true if pos is found in queue. Position 0 is top.
private:
struct Node
{
T value;
Node *next;
};
Node *first, *last;
uint size;
Node *GetPositionAddress(uint pos);
Node *GetValueAddress(T value);
};
template <class T>
class Deque
{
public:
Deque();
~Deque();
void PushBack(T value);
void PushFront(T value);
void Display();
T PopFront();
T PeekFront();
T PopEnd();
T PeekEnd();
T GetPositionValue(uint pos);
T GetMin();
T GetMax();
uint Distance(T value);
uint GetSize() const { return size; }
bool IsEmpty() { return (first == nullptr); }
bool HasValue(T value);
bool HasPosition(uint pos);
private:
struct Node
{
T value;
Node *next;
};
Node *first, *last;
uint size;
Node *GetPositionAddress(uint pos);
Node *GetValueAddress(T value);
};
#include "Queue.cpp"
#endif
这是队列的使用位置。
#include "../Headers/queue.h"
// Simple linked list of queues
struct SLLQ
{
Deque<int> deq;
SLLQ *next;
};
void CreateStorage(SLLQ *&head, SLLQ *&tail)
{
SLLQ *elem = new SLLQ;
elem->next = NULL;
if (!head)
{
head = elem;
tail = elem;
}
else
{
tail->next = elem;
tail = elem;
}
}
int main()
{
std::ifstream f("Inputs/hw4p7.in");
int k, k2, n;
Queue<int> laneIN, laneOUT;
SLLQ *sqf = NULL, *sql = NULL;
f >> k;
k2 = k;
f >> n;
for (int i = 0; i < n; i++)
{
int value;
f >> value;
laneIN.Push(value);
}
k--;
CreateStorage(sqf, sql);
sqf->deq.PushBack(laneIN.Pop());
// Inserting the wagons in the storage lines
for (int i = 1; i < n; i++)
{
if (sqf->deq.PeekEnd() < laneIN.Peek())
sqf->deq.PushBack(laneIN.Pop());
else
{
SLLQ *temp = sqf;
bool pushed = false;
while (!pushed)
{
if (!temp->next)
{
// End the program if he use to much storage lanes
if (!k)
{
std::cout << "There's no strategy with " << k2 << " storage lanes.";
_getch();
return;
}
k--;
CreateStorage(sqf, sql);
temp = temp->next;
temp->deq.PushBack(laneIN.Pop());
pushed = true;
}
else
{
temp = temp->next;
if (temp->deq.PeekEnd() < laneIN.Peek())
{
temp->deq.PushBack(laneIN.Pop());
pushed = true;
}
}
}
}
}
// Inserting the wagons in the out lane
for (int i = 0; i < n; i++)
{
SLLQ *temp = sqf;
Deque<int> mina = temp->deq;
temp = temp->next;
while (temp)
{
if (temp->deq.PeekFront() < mina.PeekFront())
mina = temp->deq;
temp = temp->next;
}
SLLQ *minadd = sqf;
SLLQ *predminadd = sqf;
while (minadd && (minadd->deq.PeekFront() != mina.PeekFront()))
{
minadd = minadd->next;
if (predminadd->next != minadd)
predminadd = predminadd->next;
}
laneOUT.Push(minadd->deq.PopFront());
if (minadd->deq.IsEmpty())
{
delete minadd;
predminadd->next = nullptr;
}
}
laneOUT.Display();
_getch();
return 0;
}
这是包含队列成员定义的.cpp文件:
#include "queue.h"
template<class T>
Queue<T>::Queue()
{
first = last = nullptr;
size = 0;
}
template<class T>
Queue<T>::~Queue()
{
while (first)
{
typename Queue<T>::Node *del = first;
first = first->next;
delete del;
}
first = last = nullptr;
size = 0;
}
template <class T>
void Queue<T>::Push(T value)
{
typename Queue<T>::Node *elem = new Node;
elem->value = value;
elem->next = nullptr;
if (first)
last->next = elem;
else
first = elem;
last = elem;
size++;
}
template <class T>
void Queue<T>::Display()
{
typename Queue<T>::Node *temp = first;
while (temp)
{
std::cout << temp->value << "\n";
temp = temp->next;
}
}
template <class T>
T Queue<T>::Pop()
{
if (IsEmpty())
return T(-1);
T value = first->value;
typename Queue<T>::Node *temp = first;
first = first->next;
delete temp;
if (first == nullptr)
last = nullptr;
size--;
return value;
}
template <class T>
T Queue<T>::Peek()
{
if (IsEmpty())
return T(-1);
return first->value;
}
template <class T>
T Queue<T>::GetPositionValue(uint pos)
{
if (IsEmpty() || !HasPosition(pos))
return T(-1);
typename Queue<T>::Node *temp = first;
for (uint i = 1; i < pos; i++)
temp = temp->next;
return temp->value;
}
template <class T>
uint Queue<T>::Distance(T value)
{
uint distance = 0;
if (!HasValue(value))
return -1;
typename Queue<T>::Node *temp = first;
while (temp && temp->value != value)
{
temp = temp->next;
distance++;
}
return distance;
}
template <class T>
T Queue<T>::GetMin()
{
if (IsEmpty())
return T();
T min = first->value;
typename Queue<T>::Node *temp = first;
while (temp->next)
{
temp = temp->next;
if (temp->value < min)
min = temp->value;
}
return min;
}
template <class T>
T Queue<T>::GetMax()
{
if (IsEmpty())
return T();
T max = first->value;
typename Queue<T>::Node *temp = first;
while (temp->next)
{
temp = temp->next;
if (temp->value > max)
max = temp->value;
}
return max;
}
template <class T>
bool Queue<T>::HasValue(T value)
{
typename Queue<T>::Node *temp = first;
while (temp && temp->value != value)
temp = temp->next;
if (!temp)
return false;
else
return true;
}
template <class T>
bool Queue<T>::HasPosition(uint pos)
{
if (IsEmpty())
return false;
uint i = 1;
typename Queue<T>::Node *temp = first;
while (temp && i < pos)
{
temp = temp->next;
i++;
}
if (i == pos)
return true;
else
return false;
}
// Private members
template <class T>
typename Queue<T>::Node *Queue<T>::GetPositionAddress(uint pos)
{
if (IsEmpty() || !HasPosition(pos))
return nullptr;
Node *temp = first;
for (uint i = 1; i < pos; i++)
temp = temp->next;
return temp;
}
template <class T>
typename Queue<T>::Node *Queue<T>::GetValueAddress(T value)
{
if (IsEmpty() || !HasValue(value))
return nullptr;
Node *temp = first;
while (temp->value != value)
temp = temp->next;
return temp;
}
// Deque
template <class T>
Deque<T>::Deque()
{
first = last = nullptr;
size = 0;
}
template <class T>
Deque<T>::~Deque()
{
while (first)
{
typename Deque<T>::Node *del = first;
first = first->next;
delete del;
}
first = last = nullptr;
size = 0;
}
template <class T>
void Deque<T>::PushBack(T value)
{
typename Deque<T>::Node *elem = new Node;
elem->value = value;
elem->next = nullptr;
if (first)
last->next = elem;
else
first = elem;
last = elem;
size++;
}
template <class T>
void Deque<T>::PushFront(T value)
{
typename Deque<T>::Node *elem = new Node;
elem->value = value;
elem->next = nullptr;
if (first)
elem->next = first;
else
last = elem;
first = elem;
size++;
}
template <class T>
void Deque<T>::Display()
{
typename Deque<T>::Node *temp = first;
while (temp)
{
std::cout << temp->value << "\n";
temp = temp->next;
}
}
template <class T>
T Deque<T>::PopFront()
{
if (IsEmpty())
return T(-1);
T value = first->value;
typename Deque<T>::Node *temp = first;
first = first->next;
delete temp;
if (first == nullptr)
last = nullptr;
size--;
return value;
}
template <class T>
T Deque<T>::PeekFront()
{
if (IsEmpty())
return T(-1);
return first->value;
}
template <class T>
T Deque<T>::PopEnd()
{
if (IsEmpty())
return T(-1);
if (first == last)
return PopFront();
T value = last->value;
typename Deque<T>::Node *temp = first;
while (temp && temp->next != last)
temp = temp->next;
delete last;
last = temp;
size--;
return value;
}
template <class T>
T Deque<T>::PeekEnd()
{
if (IsEmpty())
return T(-1);
return last->value;
}
template <class T>
T Deque<T>::GetPositionValue(uint pos)
{
if (IsEmpty() || !HasPosition(pos))
return T(-1);
typename Deque<T>::Node *temp = first;
for (uint i = 1; i < pos; i++)
temp = temp->next;
return temp->value;
}
template <class T>
uint Deque<T>::Distance(T value)
{
uint distance = 0;
if (!HasValue(value))
return -1;
typename Deque<T>::Node *temp = first;
while (temp && temp->value != value)
{
temp = temp->next;
distance++;
}
return distance;
}
template <class T>
T Deque<T>::GetMin()
{
if (IsEmpty())
return T();
T min = first->value;
typename Deque<T>::Node *temp = first;
while (temp->next)
{
temp = temp->next;
if (temp->value < min)
min = temp->value;
}
return min;
}
template <class T>
T Deque<T>::GetMax()
{
if (IsEmpty())
return T();
T max = first->value;
typename Deque<T>::Node *temp = first;
while (temp->next)
{
temp = temp->next;
if (temp->value > max)
max = temp->value;
}
return max;
}
template <class T>
bool Deque<T>::HasValue(T value)
{
typename Deque<T>::Node *temp = first;
while (temp && temp->value != value)
temp = temp->next;
if (!temp)
return false;
else
return true;
}
template <class T>
bool Deque<T>::HasPosition(uint pos)
{
if (IsEmpty())
return false;
uint i = 1;
typename Deque<T>::Node *temp = first;
while (temp && i < pos)
{
temp = temp->next;
i++;
}
if (i == pos)
return true;
else
return false;
}
// Private members
template <class T>
typename Deque<T>::Node *Deque<T>::GetPositionAddress(uint pos)
{
if (IsEmpty() || !HasPosition(pos))
return nullptr;
Node *temp = first;
for (uint i = 1; i < pos; i++)
temp = temp->next;
return temp;
}
template <class T>
typename Deque<T>::Node *Deque<T>::GetValueAddress(T value)
{
if (IsEmpty() || !HasValue(value))
return nullptr;
Node *temp = first;
while (temp->value != value)
temp = temp->next;
return temp;
}
问题出在使用队列的第114行(第三行),正是:“laneOUT.Push(minadd-&gt; deq.PopFront());” 它将值放在laneOUT中,但在下一次迭代时,它会变为残值。
答案 0 :(得分:1)
将近三年之后,我遇到了我的这个老问题,并想起当时我无法修复此代码,所以我想我应该尝试一下,因为我知道的更多了。
可以在主函数的第三个for循环的第二个语句中立即发现一个很大的否定:
Deque<int> mina = temp->deq;
此代码执行复制,但是Deque类虽然管理资源,但没有明确实现复制构造函数。
隐式复制构造函数将执行浅表复制,并且在for循环的第一次迭代之后,将销毁mina对象,但仍由temp-> deq指向用于初始化mina的已释放内存,第一次迭代,不知道它指向的内存已被释放。
The Rule of Three(在C ++ 11中为Five),当类管理资源时必须遵守。