2016-03-29 35 views
0

bu yüzden aşağıdaki kod için aşağıdaki listeye sahibim. Kopyalama/taşıma yapıcılar ve operatörler oluşturmam gerekiyor. Doğru şekilde nasıl yapılacağı konusunda sıkıntı yaşıyorum.Bağlantılı Liste Kopyala/Taşı semantik C++

Kodun mükemmel olmadığını biliyorum, tüm ipuçlarını takdir edeceğim, ancak esas olarak kopyala/taşın anlamıyla odaklanmak istiyorum.

#include <iostream> 
#include <string> 
#include <stdexcept> 

using namespace std; 

class List { 
    class Node { 
     Node* next; 
     string text; 
     int index; 
     friend class List; 
     public: 
     Node(const string& value, int i) : next(nullptr), index(i), text(value) {} 
     friend ostream& operator<< (ostream& wy, const Node& wzl) { 
      if (wzl.next) return wy << wzl.text << ", " << *wzl.next; 
      else return wy << wzl.text; 
     } 
    }; 

    Node* head; 

    int _size(Node* node, int size = 0) { 
     if (node == NULL) { 
      return size; 
     } else { 
      _size(node->next, size+1); 
     } 
    } 

    void _insert(Node* node, const string& value, int index) { 
     if (node->next == NULL || node->next->index > index) { 
      if (node->index == index) { 
       node->text = value; 
      } else { 
       Node* element = new Node(value, index); 
       element->next = node->next; 
       node->next = element; 
      } 
     } else { 
      _insert(node->next, value, index); 
     } 
    } 

    string _read(Node* node, int index) { 
     if (node->next != NULL && node->next->index <= index) { 
      return _read(node->next, index); 
     } else if (node->index == index) { 
      return node->text; 
     } else { 
      throw invalid_argument("No such index"); 
     } 
    } 

    void _remove(Node* node, int index) { 
     if (node->next != NULL && node->next->index < index) { 
      _remove(node->next, index); 
     } else if (node->next->index == index) { 
      Node* temp; 

      if (node->next->next != NULL) { 
       int temp_index = node->next->next->index; 
       temp = new Node(node->next->next->text, temp_index); 
       if (node->next->next->next != NULL) { 
        temp->next = node->next->next->next; 
       } else { 
        temp->next = NULL; 
       } 
       temp->index = node->next->next->index; 
      } else { 
       temp = nullptr; 
      } 

      delete node->next; 
      node->next = temp; 
     } else { 
      throw invalid_argument("No such index"); 
     } 
    } 

public: 
    List() : head(nullptr){}; 
    List(const List &lst) : head(nullptr) { 
     Node* tmp_lst = lst.head; 
     Node* tmp_this = this->head; 

     while (tmp_lst != NULL) { 
      // cerr << this->head->text; 
      tmp_this = new Node(tmp_lst->text, tmp_lst->index); 
      tmp_this = tmp_this->next; 
      tmp_lst = tmp_lst->next; 
     } 
    } 
    List(List&& lst); 
    List(initializer_list<string> lst) : List() { 
     Node* tmp; 
     int pos = 0; 
     for (auto element : lst) { 
      if (this->head != NULL){ 
       tmp->next = new Node(element, pos); 
       tmp = tmp->next; 
       pos++; 
      } else { 
       this->head = new Node(element, pos); 
       tmp = this->head; 
       pos++; 
      } 
     } 
    }; 
    List& operator= (const List& lst) { 
     if (this != &lst) { 
      delete this->head; 

      this->head = nullptr; 

      Node* tmp_lst = lst.head; 
      Node* tmp_this = this->head; 

      while (tmp_lst != NULL) { 
       tmp_this = new Node(tmp_lst->text, tmp_lst->index); 
       tmp_this = tmp_this->next; 
       tmp_lst = tmp_lst->next; 
      } 
     } 
     return *this; 
    } 
    List& operator= (List&& lst); 
    ~List(){ 
     delete head;  
    }; 

    void insert(const string& value, int pos) { 
     if (pos < 0) { 
      throw invalid_argument("Position cant be negative"); 
     } 

     if (this->head == NULL) { 
      Node* new_head = new Node(value, pos); 
      this->head = new_head; 
     } else if (this->head->index > pos) { 
      Node* new_head = new Node(value, pos); 
      new_head->next = this->head; 
      this->head = new_head; 
     } else { 
      _insert(this->head, value, pos); 
     } 
    } 

    string read(int pos) { 
     return _read(this->head, pos); 
    }  

    int size() { 
     return _size(this->head); 
    } 

    void remove(int pos) { 
     return _remove(this->head, pos); 
    } 

public: 
    friend ostream& operator<< (ostream& wy, const List& lst) { 
     if (lst.head) return wy << "(" << *lst.head << ")"; 
     else return wy << "()"; 
    } 
}; 

int main() { 
    return 0; 
} 

cevap

2

Sen List kopya-yapıcı ciddi kusurludur:

  • Sen boş gösterici ilk şey yapmanız önemi yok çünkü yukarıda
  • olduğunu this->head değerine tmp_this başlatmak Döngüde yeni Node nesnesini işaret edecek tmp_this yeniden atandı.
  • Ardından, tmp_this null işaretçisi olan tmp_this->next'u yeniden işaretleyerek bu işaretçiyi hemen atarsınız.
  • Ve hiçbir şeyi listeye bağlamazsınız.

Bir çalışma fonksiyonu

List(const List &lst) : head(nullptr) { 
    Node* tmp_lst = lst.head; 
    Node** tmp_current = &head; 

    while (tmp_lst != NULL) { 
     Node* tmp_this = new Node(tmp_lst->text, tmp_lst->index); 

     // Would prefer to use the copy-constructor here too, instead of the above 
     // Node* tmp_this = new Node(tmp_lst); 

     // This links the new node into the end of the list 
     *tmp_current = tmp_this 
     tmp_current = &tmp_this->next; 

     tmp_lst = tmp_lst->next; 
    } 
} 
gibi bir şey olabilir