Класс стека в C++


Пожалуйста, ознакомьтесь с этим:

#include <iostream>
#include <vector>
#include <cassert>
using namespace std;

template <class T>
class Stack
{
public:
  Stack() {}
  void push(T x);
  void pop();
  T & top();
  size_t size();
  bool empty();
private:
  std::vector<T> elems;
};

template <class T>
void Stack<T>::push(T x)
{
  elems.push_back(x);
}

template <class T>
void Stack<T>::pop()
{
  if (elems.size() > 0)
    {
      elems.erase(elems.end() - 1);
    };
}

template <class T>
T & Stack<T>::top()
{
  assert(elems.size() > 0);
  return elems.at(elems.size()-1);
}

template <class T>
size_t Stack<T>::size()
{
  return elems.size();
}

template <class T>
bool Stack<T>::empty()
{
  return elems.size() == 0 ? true : false;
}

int main()
{

  Stack<int> s;
  s.push(1);
  s.push(2);
  s.push(3);
  s.push(4); 
  s.push(5);

  cout << "size: " << s.size() << endl;
  cout << "top element: " << s.top() << endl;

  s.pop();
  s.pop();

  cout << "size: " << s.size() << endl;
  cout << "top element: " << s.top() << endl;
  cout << "empty: " << s.empty() << endl;

  s.pop();
  s.pop();
  s.pop();

  cout << "size: " << s.size() << endl;
  //cout << "top element: " << s.top() << endl;
  cout << "empty: " << s.empty() << endl;

  return 0;
}


13204
1
задан 7 сентября 2011 в 06:09 Источник Поделиться
Комментарии
3 ответа

Я согласен с Локи на размер() метод.

Может быть, утверждать не нужная вещь здесь.

template <class T>
T & Stack<T>::top()
{
assert(elems.size() > 0);
return elems.at(elems.size()-1);
}

Может быть, исключение будет лучше.
Таким образом пользователь имеет потенциал для восстановления, но если они не специально проверить, тогда приложение еще выходы, как утверждают. Утверждает также может быть включен. Так что есть вероятность, что производство код вы получите незаконный доступ к базовому вектору.

Почему бы не иметь один и тот же тест на pop (), а не молча терпеть неудачу в этой ситуации?

template <class T>
void Stack<T>::pop()
{
if (elems.size() > 0) // This causes a silent fail
// But is the same kind of programming bug as top

2
ответ дан 7 сентября 2011 в 03:09 Источник Поделиться

В большинстве случаев, я писал на другой ваш вопрос также применимы здесь. Вот еще что:

возвращение элемс.размер() == 0 ? истина : ложь;

Выражение элемс.размер() == 0 имеет тип bool. То что вы пишете это как если(истина) возвращает true; иначе возвращает false;.

3
ответ дан 7 сентября 2011 в 06:09 Источник Поделиться


  • Методы размер() и порожних() должны быть объявлены как const. Там также должна быть перегружена сверху() константный метод.

  • Вместо элемс.в(элемс.размер()-1) использование элемс.назад(). Существует также метод pop_back().

  • Не использовать с помощью пространства имен std, особенно в заголовочных файлах.

  • Реализация этих методов действительно мало, поэтому я бы рекомендовал определения внутри объявления класса.

  • Было бы неплохо иметь конструктор, который принимает ожидаемый размер стека и зарезервировать эту сумму в элемс.

  • С помощью функции assert() обязательным условием будет снят в режиме release – использовать исключения.


#include <vector>
#include <stdexcept>

template <class T>
class Stack {
public:
Stack(size_t size = 0) {
elems.reserve(size);
}

void push(T x) {
elems.push_back(x);
}

void pop() {
if (!empty()) {
elems.pop_back();
}
}

T& top() {
if (empty()) {
throw std::out_of_range("Stack is empty");
}
return elems.back();
}

T top() const {
if (empty()) {
throw std::out_of_range("Stack is empty");
}
return elems.back();
}

size_t size() const {
return elems.size();
}

bool empty() const {
return size() == 0;
}

private:
std::vector<T> elems;
};

0
ответ дан 19 апреля 2013 в 11:04 Источник Поделиться