So, I’ve been on the process of making a linked list class, and right now I’m trying to make it so that two lists can be united through simple a + operator. Here is the current code, whole:
#include <iostream>
using namespace std;
// ---/ List Class /--- //
template <class Type>
struct Node {
Type core;
Node<Type> *next;
};
template <class Type>
class List {
public:
Node<Type> *start, *end;
unsigned int siz;
static const int END;
public:
// Genesis
List() {
start = NULL;
end = NULL;
siz = 0;
};
// ---
void push (const Type&, const int&);
// DEBUG
void show (void);
// +-*/
List operator+ (const List&);
List& operator= (const List&);
List& operator+= (const List&);
// Abbadon
~List() {
delete start;
delete end;
};
};
template <class Type>
const int List<Type>::END = -1;
// ---
template <class Type>
void List<Type>::push (const Type& elem, const int& pos = END) {
Node<Type> *aux;
aux = new Node<Type>;
aux->core = elem;
if (siz == 0) {
aux->next = NULL;
start = aux;
end = aux;
}
else {
if (pos == END) {
aux->next = NULL;
end->next = aux;
end = end->next;
}
else if (pos == 0) {
aux->next = start;
start = aux;
}
else {
Node<Type> *pesq = start;
for (int i = 1; (i < pos) && (pesq->next != NULL); i++) {
pesq = pesq->next;
}
aux->next = pesq->next;
pesq->next = aux;
}
}
siz++;
}
// DEBUG
template <class Type>
void List<Type>::show (void) {
Node<Type> *pesq = start;
while (pesq != NULL) {
cout << pesq->core << endl;
pesq = pesq->next;
}
cin.get();
}
// +-*/
template <class Type>
List<Type> List<Type>::operator+ (const List<Type>& nimda) {
List<Type> aux = *this;
aux.end->next = nimda.start;
aux.end = nimda.end;
aux.siz += nimda.siz;
return aux;
}
template <class Type>
List<Type>& List<Type>::operator= (const List<Type>& nimda) {
if (&nimda != this) {
start = nimda.start;
end = nimda.start;
siz = nimda.siz;
}
}
template <class Type>
List<Type>& List<Type>::operator+= (const List<Type>& nimda) {
*this = *this + nimda;
return *this;
}
// ---/ MAIN() /--- //
int main() {
List<int> adabo;
List<int> inakos;
adabo.push(1);
adabo.push(2);
inakos.push(3);
inakos.push(4);
adabo = adabo + inakos;
adabo.show();
}
Here are the overloaded operators:
template <class Type>
List<Type> List<Type>::operator+ (const List<Type>& nimda) {
List<Type> aux = *this;
aux.end->next = nimda.start;
aux.end = nimda.end;
aux.siz += nimda.siz;
return aux;
}
template <class Type>
List<Type>& List<Type>::operator= (const List<Type>& nimda) {
if (&nimda != this) {
start = nimda.start;
end = nimda.start;
siz = nimda.siz;
}
}
template <class Type>
List<Type>& List<Type>::operator+= (const List<Type>& nimda) {
*this = *this + nimda;
return *this;
}
And here is the main(), for testing:
// ---/ MAIN() /--- //
int main() {
List<int> adabo;
List<int> inakos;
List<int> foo;
adabo.push(1);
adabo.push(2);
inakos.push(3);
inakos.push(4);
foo = adabo + inakos;
foo.show();
}
Its output would supposedly be the values 1, 2, 3, and 4, and it indeed happens when I put the show function in the operator of + before aux returns:
template <class Type>
List<Type> List<Type>::operator+ (const List<Type>& nimda) {
List<Type> aux = *this;
aux.end->next = nimda.start;
aux.end = nimda.end;
aux.siz += nimda.siz;
aux.show() // Putting it here shows everything as expected
return aux;
}
It seems, however, that ‘aux’ is lost somewhere between its return of the function and the actual value received by ‘foo’ in main(), causing foo.show() to display random data endlessly.
What am I doing wrong?
Nevermind, found the problem!
What was happening was that operator= was making a ‘duplicate’, if one so can say, of the List to be passed over. The ‘duplicate’ List, when modified, would modify the original List as well, so in here…
To solve this problem, instead of blandly passing over the pointers in the overloaded =…
…now it is made so that each element of the List is copied one by one:
This way, the receiving List gets a copy of all the elements of the original List without becoming itself.