Переполнение стека в конструкторе копирования круговых двусвязных списков

Я пытаюсь внедрить конструктор копирования в свой круговой двусвязный список, но не могу заставить его работать. Файлы копируются, но не в правильном порядке. (НОТА: plate определяется как template<typename T>, и я постараюсь включить только соответствующие функции)

Учебный класс:

plate class CircularDoubleDirectedList : public ICircularDoubleDirectedList<T> {
private:
plate class Node {
public:
T data;
Node *next;
Node *prev;
};
Node<T> *current;
int nrOfElements;
direction currentDirection;
public:
CircularDoubleDirectedList() { nrOfElements = 0; currentDirection = FORWARD; current = nullptr; }
virtual ~CircularDoubleDirectedList();
CircularDoubleDirectedList(const CircularDoubleDirectedList<T>& origObj);
CircularDoubleDirectedList& operator=(const CircularDoubleDirectedList<T>& origObj);
void addAtCurrent(const T& element);
T getElementAtCurrent() const;
void removeAtCurrent();
int size() const;
void changeDirection();
void moveCurrent();
direction getCurrentDirection() const;
};

Моя попытка на конструкторе копирования:

plate CircularDoubleDirectedList<T>::CircularDoubleDirectedList(const CircularDoubleDirectedList<T>& origObj) {
current = nullptr;
nrOfElements = 0;
Node<T> *tmp = origObj.current;
currentDirection = origObj.currentDirection;

while (nrOfElements < origObj.nrOfElements) {
addAtCurrent(tmp->data);
tmp = tmp->next;
}
}

Сумматор:

plate void CircularDoubleDirectedList<T>::addAtCurrent(const T& element) {
Node<T> *tmp = new Node<T>;
tmp->data = element;
tmp->next = nullptr;
tmp->prev = nullptr;

if (current == nullptr) {
tmp->next = tmp;
tmp->prev = tmp;
}

else if (nrOfElements == 1) {
tmp->next = current;
tmp->prev = current;
current->next = tmp;
current->prev = tmp;
}

else {

if (currentDirection == FORWARD) {
tmp->prev = current;
tmp->next = current->next;
current->next->prev = tmp;
current->next = tmp;
}

else if (currentDirection == BACKWARD) {
tmp->prev = current->prev;
tmp->next = current;
current->prev->next = tmp->prev;
current->prev = tmp;
}
}

nrOfElements += 1;
current = tmp;
}

Спасибо.

0

Решение

Как я указал в комментарии, проблема, похоже, заключается в последней функции. Поэтому я пытаюсь написать это с нуля более читабельным способом:

plate void CircularDoubleDirectedList<T>::addAtCurrent(const T& element) {
Node<T> *tmp = new Node<T>;
tmp->data = element;

if (current == nullptr) {
tmp->next = tmp;
tmp->prev = tmp;
} else {
Node<T> * before, after;
if (currentDirection == FORWARD) {
before = current;
after = current->next;
} else {  // BACKWARD
before = current->prev;
after = current;
}

before->next = tmp;
tmp->prev = before;
after->prev = tmp;
tmp->next = after;
}

nrOfElements += 1;
current = tmp;
}

Я вижу еще одну проблему в конструкторе копирования: если currentDirection имеет значение Backward, вы читаете элементы слева направо, но добавляете элементы «потом», с последующей потерей порядка.
Есть два решения: вы можете соблюдать порядок во время сканирования или установить currentDirection на FORWARD, а затем установить его на правильное значение.

plate CircularDoubleDirectedList<T>::CircularDoubleDirectedList(const CircularDoubleDirectedList<T>& origObj) {
current = nullptr;
nrOfElements = 0;
currentDirection = FORWARD;  // set the scan direction temporarily

for (Node<T> *tmp = origObj.current; nrOfElements < origObj.nrOfElements; tmp = tmp->next) {
addAtCurrent(tmp->data);
}
if (nrOfElements > 0)
current = current->next;  // align with the current of the copyed list
currentDirection = origObj.currentDirection;  // set the right direction
}

пожалуйста, дайте мне знать, если это решит вашу проблему.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector