Это глубокая копия и правильно реализованный оператор = для C ++ Linked List? - PullRequest
2 голосов
/ 19 апреля 2011

Теперь я сталкиваюсь с некоторыми ошибками, когда пытаюсь использовать созданный мной класс двусвязных списков. Моя реализация оператора = выглядит следующим образом:

template <typename T>
Dlist<T>& Dlist<T>::operator=(const Dlist &l)
{
    copyAll(l);
    return *this;
}

template <typename T>
void Dlist<T>::copyAll(const Dlist &l)
{
    node *copyList = new node;
    copyList = l.first;
    while(copyList){
        insertFront(copyList.first->o);
        copyList = copyList->next;
    }
    delete copyList;
}

Обратите внимание, что o является указателем для данных в узле в списке.

Мое намерение состоит в том, чтобы copyAll была истинной глубокой копией. Разве это не так? Что-то не так с моими определениями методов класса? Я новичок в связанных списках, поэтому помощь очень ценится!

РЕДАКТИРОВАТЬ: конкретно проблема, с которой я сталкиваюсь, заключается в том, что я делаю Список и заполняю его, затем создаю новый список и устанавливаю его равным первому, каждый раз, когда я делаю что-то со вторым списком, он также изменяет первый список ,

РЕДАКТИРОВАТЬ2: Вот сам класс. Мне не разрешено добавлять какие-либо другие функции-члены:

template <typename T>
class Dlist {
 public:

    // Operational methods

    bool isEmpty();
    // EFFECTS: returns true if list is empty, false otherwise

    void insertFront(T *o);
    // MODIFIES this
    // EFFECTS inserts o at the front of the list

    void insertBack(T *o);
    // MODIFIES this
    // EFFECTS inserts o at the back of the list

    T *removeFront();
    // MODIFIES this
    // EFFECTS removes and returns first object from non-empty list
    //         throws an instance of emptyList if empty

    T *removeBack();
    // MODIFIES this
    // EFFECTS removes and returns last object from non-empty list
    //         throws an instance of emptyList if empty

    // Maintenance methods
    Dlist();                                   // ctor
    Dlist(const Dlist &l);                     // copy ctor
    Dlist &operator=(const Dlist &l);          // assignment
    ~Dlist();                                  // dtor

 private:
    // A private type
    struct node {
    node   *next;
    node   *prev;
    T      *o;
    };

    node   *first; // The pointer to the 1st node (NULL if none)
    node   *last;  // The pointer to the 2nd node (NULL if none)


    void makeEmpty();
    // EFFECT: called by constructors/operator= to establish empty
    // list invariant

    void removeAll();
    // EFFECT: called by destructor/operator= to remove and destroy
    // all list elements

    void copyAll(const Dlist &l);
    // EFFECT: called by copy constructor/operator= to copy elements
    // from a source instance l to this instance
 };

Ответы [ 2 ]

3 голосов
/ 19 апреля 2011

В основном разница между мелкой копией и глубокой копией заключается в том, копируете ли вы только сам указатель или копируете все данные, на которые указывает указатель.Не забудьте также вызвать базовый класс и скопировать все его члены, чтобы избежать частичной инициализации, если ваш объект является производным!

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

От того, правильно ли вы это делаете, зависит от деталей реализацииваш класс, большинство из которых вы не показали здесь.То, что вы показали, выглядит неполным.

Возможно, вы захотите использовать std::list, пока не ознакомитесь с C ++ и структурами данных, прежде чем пытаться реализовать и свою собственную версию.В настоящее время редко нужно изобретать велосипед, кроме как для любопытства или для более полного изучения основных понятий.

2 голосов
/ 19 апреля 2011

Вы говорите "некоторые ошибки".Полезно упомянуть, что это такое, когда задаете вопрос.Первая строка выделяет новый узел, вторая перезаписывает этот указатель, теряя его навсегда.Может быть, вы имели в виду copyList.first = l.first.Вам также нужно будет создать новые узлы внутри цикла while.

...