2012-04-09 3 views
0

Я пытался использовать метод оператора перегрузки для копирования записей одной очереди в другую, но я ошибаюсь в своей функции. Я не знаю, как еще получить доступ к значениям очереди «оригинал» иначе, чем то, что я ниже:Перегрузка оператора для очереди C++

struct Node 
{ 
    int item; 
    Node* next; 
}; 

class Queue 
{ 
public: 
    // Extra code here 
    void operator = (const Queue &original); 
protected: 
    Node *front, *end; 
}; 

void Queue::operator=(const Queue &original) 
{ 
    //THIS IS WHERE IM GOING WRONG 
    while(original.front->next != NULL) { 
     front->item = original.front->item; 
     front->next = new Node; 
     front = front->next; 
     original.front = original.front->next; 
    } 
} 
+3

Существует уже класс 'std :: queue'. – Griwes

ответ

1
void Queue::operator=(const Queue &original) 
{ 
    Node* tmp = original.front; 
    //THIS IS WHERE IM GOING WRONG 
    while(tmp->next != NULL) { 
     front->item = tmp->item; 
     front->next = new Node; 
     front = front->next; 
     tmp = tmp->next; 
    } 
} 
+0

Разве это не то, что я делаю? – Josh

+0

Нет. Вы всегда модифицируете переднюю часть своей версии. В приведенной выше версии модифицируется перед запуском, но не в цикле, поэтому фронт не меняется и указывает на начало очереди. – Glenn

+0

Фу, я думал, что идея проста - есть разница в том, что вы изменяете. в вашем примере вы меняете объект в ссылке, в моем случае у вас есть собственная переменная, которую вы можете изменить. – nothrow

3

У вас есть функциональный конструктор копирования? Если да, то я бы реализовать оператор присваивания с точки зрения вашего конструктора копии, как так:

#include <algorithm> // <utility> for C++11 

void Queue::operator=(const Queue &other) 
{ 
    // Assumes your only field is the "front" pointer. 

    Queue tmp(other); // May throw. 
    std::swap(front, tmp.front); // Will not throw. 
} 

Идея заключается в том, что вы выполняете какие-либо операции, которые могут бросить исключение (например, ваш призыв к operator new()) на стороне в временный объект, который будет очищать ресурсы, а затем «фиксировать» ваши изменения, заменяя содержимое в операции без металирования, чтобы состояние вашего Queue было нормальным, даже если при построении tmp было выбрано исключение. Назначение указателя гарантированно не выбрасывается, поэтому вызов std::swap() не бросается в этом случае. После выхода из области действия вашего оператора назначения деструктор tmp должен очистить ваш старый список ссылок, так как его front был заменен вашим старым front.

Подробнее об этом GotW #59 «« »« Идиома »и о том, как она относится к сильной гарантии безопасности.

Смежные вопросы