2016-04-18 5 views
-1

Ich versuche, 2 Listen zu lesen und verketten sie überladen + Operator. Ich bin ziemlich neu in den Klassen, also bitte habe Geduld mit mir, alles was ich will, ist zu lernen. Ich habe die Stream-Operatoren überlastet, damit ich die Objekte normal und umgekehrt lesen und schreiben kann. My + -Operator verkettet die Listen, aber die Probleme scheinen in main zu sein (list1 = list1 + list2; oder list3 - nach Verkettung von list1 und list2). Ich suchte fast überall im Internet nach einer Antwort und beendete das Posting. Wenn Sie Links oder Tutorials haben, die mich schneller und einfacher wachsen lassen, bin ich offen für neue Ideen. Vielen viel für das Lesen und tryng zu ^^Überladen + Operator zum Verketten von 2 doppelten Listen

Knotenklasse helfen:

class nod 
{ 
public: 
    int data; 
    nod *next; 
    nod *prev; 
    friend class Lista; 
    nod(); 
}; 

Liste Klasse

class Lista 
{ 
private: 
    nod *head; 
    nod *tail; 
    int size; 
public: 
    Lista(); 
    ~Lista(); 
    friend istream &operator >>(istream &input, Lista &a) 
    { 
     int i; 
     cout << "Size of the list: "; 
     input >> a.size; 
     nod *q = new nod; 
     q->prev = NULL; 
     cout << "\nFrist node: "; 
     input >> q->data; 
     a.head = q; 
     a.tail = a.head; 
     for (i = 1; i < a.size; i++) 
     { 
      nod *q = new nod; 
      cout << "\nNode number " << i + 1 << " is: "; 
      input >> q->data; 
      a.tail->next = q; 
      q->prev = a.tail; 
      a.tail = q; 
      a.tail->next = NULL; 
     } 
     return input; 
    } 

    friend ostream& operator <<(ostream &output, Lista &a) 
    { 
     output << "\n\nNormal writing: "; 
     nod *q = new nod; 
     q = a.head; 
     while (q != NULL) 
     { 
      output << q->data << " "; 
      q = q->next; 
     } 
     q = a.tail; 
     output << "\n\nReverse writing: "; 

     while (q != NULL) 
     { 
      output << q->data << " "; 
      q = q->prev; 
     } 
     return output; 
    } 
    Lista &operator+(Lista &rec) 
    { 
     Lista temp; 
     temp.head = head; 
     temp.tail = tail; 
     temp.tail->next = rec.head; 
     rec.head->prev = temp.tail; 
     temp.tail = rec.tail; 
     temp.size = size; 
     temp.size = temp.size + rec.size; 
     return temp; 
    } 
}; 

Main:

int main() 
{ 
    Lista a,b,c; 
    cin>>a; 
    cin>>b; 
    c=a+b; 
    cout<<c; 
    return 0; 
} 
+2

Du verfolgst nicht [der Regel von 3] (http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three) . Sie können möglicherweise nichts mit 'operator +' anfangen, bis Sie einen benutzerdefinierten Kopierkonstruktor schreiben. Auch diese Art der Codierung ist nicht für Anfänger, sondern für erfahrene C++ - Programmierer. Ich muss noch sehen, dass ein Anfänger das richtig macht, ohne dass ein erfahrener Programmierer das Ganze für sie geschrieben hat. – PaulMcKenzie

+0

Also wenn ich "c = a + b" verwenden möchte, muss ich auch den = Operator überladen? –

+1

Sie müssen die Regel von 3 befolgen. Das heißt, Sie müssen den Kopierkonstruktor, den Zuweisungsoperator und den Destruktor implementieren, * und sie müssen korrekt arbeiten *. Was Sie bereits programmiert haben, gibt es viele Dinge, die anders gemacht werden sollten - was ist, wenn ich ein Element zur Liste hinzufügen möchte, und ich möchte keinen Stream verwenden? Wie mein erster Kommentar andeutet, wird dies zu mir oder einem anderen SO-Mitglied, das Sie entweder zum bereits geschriebenen Code führt, oder wir schreiben das Ganze selbst, um Ihnen zu zeigen, wie Sie das richtig machen. Ein Anfänger * nie * bekommt das richtig, glaub mir. – PaulMcKenzie

Antwort

0

Ihre operator+ ist nicht einmal in der Nähe eine korrekte Implementierung sein. Für den Anfang geben Sie eine Referenz auf eine lokale Variable zurück, die beim Beenden den Gültigkeitsbereich verlässt, die Liste zerstört und den Aufrufer mit einer falschen Referenz auf ungültigen Speicher belässt. Aber schlimmer noch, Sie machen diesen lokalen Variablenpunkt an den Knoten Ihrer Eingabelisten und Sie manipulieren die verschiedenen Zeiger in diesen Listen, wodurch beide Listen beschädigt werden.

operator+ muss eine Kopie der Daten aus den zwei Eingangslisten zurückgeben. Das bedeutet, dass der Ausgabeliste ein ganz neuer Knotensatz zugewiesen wird.

etwas mehr wie diese stattdessen versuchen:

class nod 
{ 
public: 
    int data; 
    nod *next; 
    nod *prev; 

    nod(int value = 0) : 
     data(value), next(NULL), prev(NULL) 
    { 
    } 
}; 

class Lista 
{ 
private: 
    nod *head; 
    nod *tail; 
    int size; 

public: 
    Lista() : 
     head(NULL), tail(NULL), size(0) 
    { 
    } 

    Lista(const Lista &src) : 
     head(NULL), tail(NULL), size(0) 
    { 
     *this = src; 
    } 

    ~Lista() 
    { 
     Clear(); 
    } 

    void Add(int value) 
    { 
     node *n = new nod(value); 
     n->prev = tail; 
     if (!head) head = n; 
     if (tail) tail->next = n; 
     tail = n; 
     ++size; 
    } 

    void Clear() 
    { 
     nod *n = head; 
     head = tail = NULL; 
     size = 0; 
     while (n) 
     { 
      nod *next = n->next; 
      delete n; 
      n = next; 
     } 
    } 

    Lista& operator=(const Lista &rhs) 
    { 
     Clear(); 
     nod *n = rhs.head; 
     while (n) 
     { 
      Add(n->data); 
      n = n->next; 
     } 
     return *this; 
    } 

    Lista operator+(const Lista &rhs) 
    { 
     Lista temp; 

     nod *n = head; 
     while (n) 
     { 
      temp.Add(n->data); 
      n = n->next; 
     } 

     n = rhs.head; 
     while (n) 
     { 
      temp.Add(n->data); 
      n = n->next; 
     } 
     return temp; 
    } 

    friend std::istream& operator >>(std::istream &input, Lista &a); 
    friend std::ostream& operator <<(std::ostream &output, const Lista &a); 
}; 

std::istream& operator >>(std::istream &input, Lista &a) 
{ 
    // NOTE: this kind of code really does not 
    // belong in an 'operator>>' implementation! 

    int i, size, data; 
    std::cout << "Size of the list: "; 
    input >> size; 
    for (i = 0; i < size; ++i) 
    { 
     std::cout << "\nNode number " << i + 1 << ": "; 
     input >> data; 
     a.Add(data); 
    } 
    return input; 
} 

std::ostream& operator <<(std::ostream &output, const Lista &a) 
{ 
    output << "\n\nNormal writing: "; 
    nod *n = a.head; 
    while (n) 
    { 
     output << n->data << " "; 
     n = n->next; 
    } 

    n = a.tail; 
    output << "\n\nReverse writing: "; 
    while (n) 
    { 
     output << n->data << " "; 
     n = n->prev; 
    } 

    return output; 
} 

int main() 
{ 
    Lista a, b, c; 
    std::cin >> a; 
    std::cin >> b; 
    c = a + b; 
    std::cout << c; 
    return 0; 
} 

Jetzt, mit dieser sagte, Sie ernsthaft Umsetzung der manuellen los verketteten Liste bekommen sollte und stattdessen die Klasse STL std::list verwenden, die eine verknüpfte Liste von Knoten verwaltet d weiß, wie Kopien von sich selbst zu machen:

#include <list> 
#include <algorithm> 
#include <iterator> 

class Lista 
{ 
private: 
    std::list<int> data; 

public: 
    void Add(int value) 
    { 
     data.push_back(value); 
    } 

    void Clear() 
    { 
     data.clear(); 
    } 

    Lista operator+(const Lista &rhs) 
    { 
     Lista temp; 
     std::copy(data.begin(), data.end(), std::back_inserter(temp)); 
     std::copy(rhs.data.begin(), rhs.data.end(), std::back_inserter(temp)); 
     return temp; 
    } 

    friend std::istream& operator >>(std::istream &input, Lista &a); 
    friend std::ostream& operator <<(std::ostream &output, const Lista &a); 
}; 

std::istream& operator >>(std::istream &input, Lista &a); 
{ 
    // NOTE: this kind of code really does not 
    // belong in an 'operator>>' implementation! 

    int i, size, data; 
    std::cout << "Size of the list: "; 
    input >> size; 
    for (i = 0; i < size; ++i) 
    { 
     std::cout << "\nNode number " << i + 1 << ": "; 
     input >> data; 
     a.Add(data); 
    } 
    return input; 
} 

std::ostream& operator <<(std::ostream &output, const Lista &a) 
{ 
    output << "\n\nNormal writing: "; 
    for (std::list<int>::const_iterator iter = a.data.begin(), end = a.data.end(); iter != end; ++iter) 
    { 
     output << *iter << " "; 
    } 

    output << "\n\nReverse writing: "; 
    for (std::list<int>::const_reverse_iterator iter = a.data.rbegin(), end = a.data.rend(); iter != end; ++iter) 
    { 
     output << *iter << " "; 
    } 

    return output; 
}