#ifndef PILHA_INT_H
#define PILHA_INT_H
/** Representa pilhas de inteiros.
@invariant 0 <= numero_de_itens <= capacidade and 0 < capacidade. */
class PilhaInt {
public:
/** Sinónimo de int, serve para simplificar a definição de pilhas de itens
com tipos diferentes. */
typedef int Item;
/// Representa condições de memória esgotada.
class MemoriaEsgotada;
// Construtores:
/// Construtor por omissão. Constrói pilha vazia.
PilhaInt();
/// Construtor por cópia. Constrói "clone" de pilha já existente.
PilhaInt(PilhaInt const& outra_pilha);
/// Destrutor.
~PilhaInt();
/** @brief Operador de atribuição por cópia.
Dada uma pilha (operando esquerdo) torna-a igual à pilha que lhe é
fornecida como modelo. Ou seja, faz uma "operação plástica" à
pilha.
Tal como no caso do construtor por cópia, também a versão da
atribuição por cópia fornecida pelo C++ dá resultados desastrosos,
fazendo com que a pilha perca partes (a matriz dinâmica) e fique a
partilhar partes com o modelo. Digamos que as duas instâncias
envolvidas são tornadas siamesas pelo cirurgião plástico... Daí a
necessidade de fornecer explicitamente este operador. */
PilhaInt& operator = (PilhaInt const& outra_pilha);
// Inspectores:
/// Devolve altura da pilha, ou seja, o seu número de itens.
int altura() const;
/// Devolve booleano indicando se a pilha está vazia.
bool estaVazia() const;
/// Devolve booleano indicando se a pilha está cheia.
bool estaCheia() const;
/** @brief Devolve item no topo da pilha sem permitir alterá-lo.
@pre ¬estaVazia(). */
Item const& topo() const;
// Modificadores:
/** @brief Devolve item no topo da pilha permitindo alterá-lo.
@pre ¬estaVazia(). */
Item& topo();
/** @brief Põe novo item no topo da pilha.
@pre ¬estaCheia(). */
void poe(Item const& novo_item);
/** @brief Tira item do topo da pilha.
@pre ¬estaVazia(). */
void tira();
private:
// Qualquer pilha terá esta capacidade inicial:
static int const capacidade_inicial = 32;
// A capacidade da pilha em cada instante. Não é uma capacidade
// definitiva, pois pode ser aumentada se houver necessidade e se houver
// memória livre disponível.
int capacidade;
// Ponteiro para o primeiro elemento da matriz dinâmica que guarda os
// itens da pilha:
Item* itens;
// Guarda o número de itens na pilha. A matriz dinâmica dos itens está
// dividida em dois trocos disjuntos. Os primeiros numero_de_itens
// elementos guardam itens da pilha. Os restantes contêm lixo.
int numero_de_itens;
// Devolve booleano indicando se o invariante da classe se cumpre:
bool cumpreInvariante() const;
};
/// Representa erros de excesso de memória associados à classe PilhaInt.
class PilhaInt::MemoriaEsgotada {
public:
/// Construtor. Recebe a dimensão pretendida para a matriz dinâmica.
MemoriaEsgotada(int dimensao_pretentida);
/// Inspector da dimensão pretendida para a matriz dinâmica.
int dimensaoPretendida();
private:
int dimensao_pretendida;
};
#include "pilha_int_impl.H"
#endif // PILHA_INT_H