В вашем классе Stack
есть несколько ошибок.
Во-первых, конструктор копирования не инициализирует все члены, как и ваш конструктор по умолчанию. Их необходимо исправить:
template <class T>
Stack<T>::Stack() : _head(nullptr), _temp1(nullptr), _temp2(nullptr) {}
template <class T>
Stack<T>::Stack(const Stack<T>& rhs) : _head(nullptr), _temp1(nullptr), _temp2(nullptr)
{
//...
}
Как только это будет сделано, конструктор копирования может быть легко реализован с помощью другой существующей функции Stack::push
. Ваша реализация слишком сложна.
template <class T>
Stack<T>::Stack(const Stack<T>& rhs) : _head(nullptr), _temp1(nullptr), _temp2(nullptr) {
Node<T>* temp = rhs._head;
while (temp)
{
push(temp->_data);
temp = temp->_next;
}
}
Что здесь делается? Просто - все, что мы делаем, это берем заголовок переданного Stack
и перебираем элементы, вызывающие Stack::push
, чтобы добавить данные в новый объект Stack
. Поскольку у вас уже закодирована функция push
, вы должны ее использовать.
Во-вторых, обратите внимание, что мы используем локальную переменную temp
. Я сомневаюсь, что вам нужен какой-либо из этих _temp
членов в вашем классе, но это другая история.
Наконец, ваш оператор присваивания можно легко реализовать, если у вас есть конструктор копирования и деструктор для Stack
:
template <class T>
const Stack<T>& Stack<T>::operator=(const Stack<T>& rhs) {
if (this != &rhs) {
Stack<T> temp = rhs;
std::swap(temp._head, _head);
std::swap(temp._temp1, _temp1);
std::swap(temp._temp2, _temp2);
}
return *this;
}
Этот метод использует копирование / свопинг . Все, что делается, - это создать временный объект из переданного объекта Stack
и просто заменить текущее содержимое содержимым временного. Затем временное отмирает со старым содержимым.
Учитывая все это, класс должен работать правильно. Правильно ли это на 100% со всеми другими функциями, это опять же другой вопрос.
Изменить:
Вот исправление для конструктора копирования. Обратите внимание, что мы по-прежнему используем существующие функции для создания копии:
template <class T>
Stack<T>::Stack(const Stack<T>& rhs) : _head(nullptr), _temp1(nullptr), _temp2(nullptr) {
Node<T>* temp = rhs._head;
Stack<T> tempStack;
while (temp)
{
tempStack.push(temp->_data);
temp = temp->_next;
}
while (!tempStack.empty())
{
push(tempStack.top());
tempStack.pop();
}
}
Это не так эффективно, но обычно структура данных стека использует базовый контейнер, такой как vector
, где легко отменить базовое содержимое , а не на основе односвязного списка, который вы используете.