HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppMinor

Extremely simple stack implementation using a vector

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
simplestackextremelyusingimplementationvector

Problem

Please review my simple Stack:

template
class Stack {
public:
    Stack() = default;
    Stack(std::initializer_list i) :n{} {
        for (auto& x : i) {
            elem.push_back(x);
            ++n;
        }
    }
    Stack(const Stack&) = default;
    Stack(Stack&&) = default;
    Stack& operator=(const Stack&) = default;
    Stack& operator=(Stack&&) = default;
    ~Stack() = default;
    int size() const {
        return n;
    }
    bool isEmpty() const {
        return (n == 0);
    }
    void push(T);
    T pop();
    T& peek();

private:
    std::vector elem;
    int n;
};

template
void Stack::push(T t) {
    elem.push_back(t);
    ++n;
}

template
T Stack::pop() {
    if (isEmpty()) {
        throw std::out_of_range("underflow");
    }
    T t = *elem.erase(elem.end()-1);
    --n;
    return t;
}

template
T& Stack::peek() {
    if (isEmpty()) {
        throw std::out_of_range("underflow");
    }
    return elem[n-1];
}


How can I make this code better and build more complicated data structures based on stacks?

Solution

Remove int n;from member variable.
Underlying container std::vector holds the size information of the stack class. It increases the size of stack class object by sizeof(int).

Remove various default definition methods from your class. Compiler would generate it for such classes. Due to these definition your class looks more verbose.

Implement all your member functions using the underlying container classes.

Prefer the standard name of your method instead of other. This way any program would easily use your custom class instead of std::stack. Change the isEmpty() to empty()

Your implementation can be simplified as below.

template
class Stack {
public:
    Stack(const std::initializer_list& i):elem(i) {}
    int size() const { return elem.size(); }
    bool empty() const { return elem.empty();}
    void push(const T&);
    T pop();
    T peek();
private:
    std::vector elem;
};

template
void Stack::push(const T& t) {
    elem.push_back(t);
}

template
T Stack::pop() {
    if (empty()) {
        throw std::out_of_range("underflow");
    }
    auto x = elem.back();  
    elem.pop_back();
    return x;
}

template
T Stack::peek() {
    if (empty()) {
        throw std::out_of_range("underflow");
    }
    return elem.back();
}

Code Snippets

template<class T>
class Stack {
public:
    Stack(const std::initializer_list<T>& i):elem(i) {}
    int size() const { return elem.size(); }
    bool empty() const { return elem.empty();}
    void push(const T&);
    T pop();
    T peek();
private:
    std::vector<T> elem;
};


template<class T>
void Stack<T>::push(const T& t) {
    elem.push_back(t);
}

template<class T>
T Stack<T>::pop() {
    if (empty()) {
        throw std::out_of_range("underflow");
    }
    auto x = elem.back();  
    elem.pop_back();
    return x;
}

template<class T>
T Stack<T>::peek() {
    if (empty()) {
        throw std::out_of_range("underflow");
    }
    return elem.back();
}

Context

StackExchange Code Review Q#69239, answer score: 4

Revisions (0)

No revisions yet.