在我自己的堆栈中实现top的问题

时间:2018-08-01 06:42:52

标签: c++ stack

我正在尝试实现自己的通用堆栈

实现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

有人可以帮助我如何解决这个问题

1 个答案:

答案 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";
}

关于一个更有用的示例,请参见下面的代码。这是通用堆栈的基本操作,包括pushpoptopclear(和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