我正在尝试实现自己的通用堆栈
实现Top Function时会遇到一些问题,该函数返回堆栈的最后一个元素
但是,当 head == NULL 时,没有任何东西可以返回
#include <iostream>
#include <string>
using namespace std;
template <class anyType>
class Stack
{
private: struct node
{
anyType data;
node* nextAddress;
};
private: node* head;
public: Stack()
{
head = NULL;
}
public: anyType Top()
{
if (head == NULL)
{
cout<<"Stack is empty"<<endl;
return NULL;
}
node* travel = head;
while(travel -> nextAddress != NULL)
{
travel = travel -> nextAddress;
}
return travel -> data;
}
};
struct Student
{
int id;
string name;
};
int main(int argc, char const *argv[])
{
Stack <Student> obj;
return 0;
}
所以,当我返回 NULL 时,就会出现问题,因为 NULL!= anyType
有人可以帮助我如何解决这个问题
答案 0 :(得分:7)
如果将函数定义为返回实际对象(而不是指向对象的指针),并且您需要指示此类对象不存在,那么执行此操作的最佳方法可能就是抛出异常。
换句话说,就像:
if (head == nullptr) {
throw std::runtime_error("stack is empty, no top");
}
然后,在调用它的代码中,您只需要考虑到这一点:
try {
processHeadSomehow(stack.Top());
} catch (std::runtime_error &e) {
std::cout << "No top element, couldn't process\n";
}
关于一个更有用的示例,请参见下面的代码。这是通用堆栈的基本操作,包括push
,pop
,top
,clear
(和dump
用于调试)。请注意,删除了将列表遍历到最后的代码。那是因为我们将项目推送到链接列表的开始,因此我们需要将其删除(用于弹出)或查看(用于顶部)。
#include <iostream>
#include <string>
#include <exception>
using std::cout; using std::string; using std::runtime_error;
template <class AnyType> class Stack {
struct Node { AnyType data; Node *next; };
public:
Stack() { m_head = nullptr; }
~Stack() { Clear(); }
void Dump() {
cout << "\n";
auto curr = m_head;
auto count = 0;
while (curr != nullptr) {
cout << "Item #" << ++count << " is " << curr->data << "\n";
curr = curr->next;
}
cout << "-- Number of items was " << count << "\n";
}
void Clear() {
auto curr = m_head;
m_head = nullptr;
while (curr != nullptr) {
Node *toFree = curr;
curr = curr->next;
delete toFree;
}
}
void Push(AnyType item) {
auto newItem = new Node;
newItem->data = item;
if (m_head == nullptr) {
newItem->next = nullptr;
m_head = newItem;
} else {
newItem->next = m_head;
m_head = newItem;
}
}
AnyType Pop() {
if (m_head == nullptr)
throw runtime_error("Stack empty");
Node *toFree = m_head;
m_head = m_head->next;
AnyType retVal = toFree->data;
delete toFree;
return retVal;
}
AnyType Top() {
if (m_head == nullptr)
throw runtime_error("Stack empty");
return m_head->data;
}
private:
Node *m_head;
};
int main(int argc, char const *argv[])
{
Stack<string> stack;
for (const string str: {"", "Pax", "Imran", "Joel"}) {
if (! str.empty())
stack.Push(str);
stack.Dump();
try {
cout << "Top of stack is " << stack.Top() << "\n";
} catch (runtime_error &e) {
cout << "Exception getting top: " << e.what() << "\n";
}
}
try {
auto popped = stack.Pop();
stack.Dump();
cout << "This is after we popped " << popped << "\n";
cout << "Top of stack is " << stack.Top() << "\n";
} catch (runtime_error &e) {
cout << "Exception getting top: " << e.what() << "\n";
}
return 0;
}
在测试main
中运行该代码时,我们会看到预期的行为:
-- Number of items was 0
Exception getting top: Stack empty
Item #1 is Pax
-- Number of items was 1
Top of stack is Pax
Item #1 is Imran
Item #2 is Pax
-- Number of items was 2
Top of stack is Imran
Item #1 is Joel
Item #2 is Imran
Item #3 is Pax
-- Number of items was 3
Top of stack is Joel
Item #1 is Imran
Item #2 is Pax
-- Number of items was 2
This is after we popped Joel
Top of stack is Imran