Abbiamo iniziato gli stack la settimana scorsa e la prof. ci ha detto di scrivere l'interfaccia base della classe (costruttori, push e pop) utilizzando come classe aggregata un single-linked node (che abbiamo già utilizzato per creare le liste).
il mio problema è nel creare il costruttore copia: da quanto ho capito bisogna passare lo stack da copiare
per copia (e quindi il ragionamento è sbagliato già da qui), copiare il contenuto dello stack dentro uno stack d'appoggio (altrimenti si avrebbero gli elementi in disposizione esattamente inversa rispetto allo stack di partenza) e poi buttare questo stack d'appoggio nello stack appena costruito (this).
appunto però, da come l'ho pensato io, vi è la necessità di passare lo stack da copiare per copia, altrimenti verrebbe modificato se lo passassi come reference (anzi, diverrebbe uno stack vuoto).
non so quindi come attuare un procedimento logico: mi è subito venuto in mente il classico scorrimento che si effettua con le liste (quello con il puntatore d'appoggio), ma non sarebbe illogico? in una pila non si possono "scorrere" gli elementi, bisogna togliere ogni volta quello in cima...
qualcuno mi saprebbe spiegare come fare un costruttore copia di uno stack? (che seguendo questo ragionamento sarebbe obbligatorio: un altro dei metodi da implementare era appunto la scansione: anche in quel caso devo passare la pila per copia... e serve appunto il costruttore copia).
la mia classe è questa:
stack.h:
#pragma once
#include "../Lista Template/nodo.cpp"
template <class T>
class Stack
{
protected:
Nodo<T>* top;
public:
Stack();
Stack(const T& val);
Stack(Stack<T> copy);
~Stack();
Nodo<T>* getTop(void);
void push(const T& val);
T pop(void);
bool isEmpty(void);
friend std::ostream& operator<<(std::ostream& output, Stack<T> stack)
{
if (stack.isEmpty())
output << "Pila vuota." << endl;
else
{
while (stack.getTop() != nullptr)
output << stack.pop() << endl;
}
return output;
}
};
stack.cpp:
#include "stack.h"
template <typename T>
Stack<T>::Stack()
{
top = nullptr;
}
template <typename T>
Stack<T>::Stack(const T& val)
{
top = new Nodo<T>(val);
}
template <typename T>
Stack<T>::Stack(Stack<T> copy) // non funzionante
{
top = nullptr;
Stack<T> temp;
while (copy.getTop() != nullptr)
temp.push(copy.pop());
this->push(temp.pop());
}
template <typename T>
Stack<T>::~Stack()
{
while (top != nullptr)
pop();
}
template <typename T>
Nodo<T>* Stack<T>::getTop(void)
{
return top;
}
template <typename T>
void Stack<T>::push(const T& val)
{
Nodo<T>* aux = new Nodo<T>(val, top);
top = aux;
}
template <typename T>
T Stack<T>::pop(void)
{
const T val = top->getValue();
Nodo<T>* aux = top->getNext();
delete top;
top = aux;
return val;
}
template <typename T>
bool Stack<T>::isEmpty(void)
{
return (top == nullptr);
}
nodo.h:
#pragma once
template <typename T>
class Node
{
protected:
T value; // valore contenuto all'interno del nodo
Node<T>* next; // puntatore all'elemento successivo
public:
/* Costruttore di default. */
Node();
/* Costruttore con parametro l'informazione del nodo. */
Node(const T& info);
/* Costruttore con parametri. */
Node(const T& info, Node<T>* next);
/* Costruttore copia. */
Node(const Node<T>& copy);
// Imposta il valore di T.
void setValue(const T& value);
// Imposta il puntatore al nodo successivo.
void setNext(Node<T>* next);
// Ottiene il valore del nodo.
T getValue(void);
// Ottiene il puntatore al nodo successivo.
Node<T>* getNext(void);
};
nodo.cpp:
#include "node.h"
template <typename T>
Node<T>::Node() : value()
{
next = nullptr;
}
template <typename T>
Node<T>::Node(const T& info)
{
value = info;
next = nullptr;
}
template <typename T>
Node<T>::Node(const T& info, Node<T>* next)
{
value = info;
this->next = next;
}
template <typename T>
Node<T>::Node(const Node<T>& copy)
{
value = copy.value;
next = copy.next;
}
template <typename T>
void Node<T>::setValue(const T& value)
{
this->value = value;
}
template <typename T>
void Node<T>::setNext(Node<T>* next)
{
this->next = next;
}
template <typename T>
T Node<T>::getValue(void)
{
return value;
}
template <typename T>
Node<T>* Node<T>::getNext(void)
{
return next;
}