我在C ++中围绕队列数据结构编写了一个应用程序,除非我想创建一个字符串对象队列,否则一切都很好。当我创建一个字符串对象的队列时,一旦我删除一个项目程序崩溃,我不知道为什么!有人可以帮忙吗?
Main.cpp的
//////////////////////////////////
// //
// Data Structures - Queues //
// ------------------------ //
// //
// Creating a queue system //
// using linked lists and //
// C++ (FIFO) //
// //
//////////////////////////////////
#include "LibIncludes.h"
#define EXIT 6
int mainMenu();
void printMessage(std::string);
void handleOption(Queue<std::string> & usersQueue, const int option);
int main()
{
Queue<std::string> usersQueue;
int usersOption = 0;
do
{
usersOption = mainMenu();
handleOption(usersQueue, usersOption);
} while (usersOption != EXIT);
return 0;
}
/////////////////////////////////////////////////////////////////////////////////
//
// FUNCTION PROTOTYPE DEFINITIONS
//
/////////////////////////////////////////////////////////////////////////////////
int mainMenu()
{
int menu_option;
std::cout << "---------------------------------------\n";
std::cout << "| |\n";
std::cout << "| Welcome to the Queue Generater! |\n";
std::cout << "| |\n";
std::cout << "---------------------------------------\n\n";
std::cout << "Available Options:\n";
std::cout << " 1) Add Item To Queue\n";
std::cout << " 2) Delete Item From Queue\n";
std::cout << " 3) Preview Next Item In Queue\n";
std::cout << " 4) View Number Of Items In Queue\n";
std::cout << " 5) Erase Entire Queue\n";
std::cout << " 6) Exit Application\n\n";
std::cout << "Option Select: ";
std::cin >> menu_option;
return menu_option;
}
void printMessage(std::string text)
{
printf("\n%s", text.c_str());
std::cout << "*** [ Press ENTER to contonue ] ***\n";
std::cin.ignore();
std::cin.get();
}
void handleOption(Queue<std::string> & usersQueue, const int option)
{
std::string item;
switch (option)
{
// add item
case 1:
std::cout << "\nEnter in the item you wish to add: ";
std::cin >> item;
usersQueue.push(item);
std::cout << "\n*** [ Success! " << item << " Was Added To The Queue ] ***";
printMessage("");
break;
// delete item
case 2:
if (usersQueue.isEmpty())
printMessage("*** [ Error: Queue Is Currently Empty ] ***\n");
else
{
auto oldItem = usersQueue.pop();
std::cout << "\n*** [ Success! " << oldItem << " was removed ] ***";
printMessage("");
}
break;
// peek item
case 3:
item = usersQueue.peek();
if (usersQueue.isEmpty())
printMessage("*** [ Error: Queue Is Currently Empty ] ***\n");
else
{
std::cout << "\n*** [ Top Item In Queue: " << item << " ] ***";
printMessage("");
}
break;
// view size
case 4:
printf("\n*** [ Queue Size: %d ] ***", usersQueue.getSize());
printMessage("");
break;
// clear queue
case 5:
if (usersQueue.pop_all() == false)
printMessage("*** [ Error: Cannot Clear An Empty Queue] ***\n");
else
printMessage("*** [ Clear Successful ] ***\n");
break;
// exit application
case 6:
printMessage("*** [ Goodbye ] ***\n");
break;
default:
printMessage("*** [ Error: Not A Valid Menu Option ] ***\n");
}
system("CLS");
}
Queue.inl
#include "LibIncludes.h"
template <typename T>
Queue<T>::Queue()
{
headNode = nullptr;
tailNode = nullptr;
size = 0;
}
///////////////////////////////////////////////////////////////////////////////
template <typename T>
Queue<T>::Queue(T newItem)
{
Node * temp = new Node;
temp->data = newItem;
temp->nextNode = nullptr;
headNode = temp;
tailNode = temp;
size = 1;
}
///////////////////////////////////////////////////////////////////////////////
template <typename T>
Queue<T>::~Queue()
{
std::cout << "Deconstructor Executing...\n";
pop_all();
delete[] headNode;
delete[] tailNode;
headNode = nullptr;
tailNode = nullptr;
}
///////////////////////////////////////////////////////////////////////////////
template <typename T>
bool Queue<T>::isEmpty()
{
if (headNode == nullptr && tailNode == nullptr)
return true;
else
return false;
}
///////////////////////////////////////////////////////////////////////////////
template <typename T>
T Queue<T>::peek()
{
if (isEmpty())
return T();
else
return headNode->data;
}
///////////////////////////////////////////////////////////////////////////////
template <typename T>
bool Queue<T>::pop_all()
{
if (isEmpty())
return false;
else
{
std::cout << "\nQueue is now deleting the following items:\n";
std::cout << "--------------------------------------------------------------\n\n";
T temp_data;
while (!isEmpty())
{
temp_data = pop();
std::cout << " - " << temp_data << "\n";
}
std::cout << "\nQueue is now empty.\n";
std::cout << "--------------------------------------------------------------\n";
return true;
}
}
///////////////////////////////////////////////////////////////////////////////
template <typename T>
void Queue<T>::push(T newItem)
{
Node * temp = new Node;
temp->data = newItem;
temp->nextNode = nullptr;
if (isEmpty())
{
headNode = temp;
tailNode = temp;
}
else
{
tailNode->nextNode = temp;
tailNode = temp;
}
size++;
}
///////////////////////////////////////////////////////////////////////////////
template <typename T>
T Queue<T>::pop()
{
if (isEmpty())
return T();
else
{
Node * temp = new Node;
temp = headNode;
T removedItem = headNode->data;
headNode = headNode->nextNode;
size--;
delete[] temp;
temp = nullptr;
if (size == 0)
{
headNode = nullptr;
tailNode = nullptr;
}
return removedItem;
}
}
///////////////////////////////////////////////////////////////////////////////
template <typename T>
int Queue<T>::getSize()
{
return size;
}
Queue.h
#pragma once
template <class T>
class Queue
{
public:
Queue();
Queue(T newItem);
~Queue();
void push(T newItem);
T pop();
T peek();
bool pop_all();
bool isEmpty();
int getSize();
private:
struct Node
{
T data;
Node * nextNode;
};
Node LinkedList;
Node * headNode; // front of the queue
Node * tailNode; // End of the Queue
int size;
};
#include "Queue.inl"
LibIncludes.h
#pragma once
#include <iostream>
#include <string>
#include "Queue.h"