Overloaded operators and Copy constructor

so I have some trouble with my code, not sure if its something wrong with the copy constructor or the overloaded insertion

this is the DoublyList.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#ifndef DOUBLYLIST_H
#define DOUBLYLIST_H

#include <string>
#include <iostream>
using namespace std;

class Node
{
public:
	Node() : data(0), prev(NULL), next(NULL) {}
	Node(int newData, Node *newPrev, Node *newNext)
		: data(newData), prev(newPrev), next(newNext) {}
	int getData() const { return data; }
	Node *getPrev() const { return prev; }
	Node *getNext() const { return next; }
	void setData(const int& newData) { data = newData; }
	void setPrev(Node *newPrev) { prev = newPrev; }
	void setNext(Node *newNext) { next = newNext; }
	bool operator==(const Node& otherNode) { return (this == &otherNode); }
	~Node() {}
private:
	int data;
	Node *prev;
	Node *next;
};


class DoublyList
{
	// Functions of Functions.cpp
	friend ostream& operator<<(ostream &out, const DoublyList& lst);


public:
	DoublyList(); 

	void insertBack(int numOfElem);
	void insertBack(const int a[], int numOfElem);

	int getFirst() const;
	int getLast() const;
	int getNumOfElem() const;
	Node* getPrevOfFirst() const;
	Node* getNextOfLast() const;	
	Node& getFirstNodeAddress() const;
	Node& getLastNodeAddress() const;
	
	void reversePrint() const;

	void destroyList();
	~DoublyList();

	// Functions of Function.cpp

	DoublyList(const DoublyList& lst);
	DoublyList& operator=(DoublyList other);



private:
    Node *first;	// pointer to the first node on the list
    Node *last;		// pointer to the last node on the list
	int count;		// number of nodes in the list
};

#endif 



This is the DoublyList.cpp insertBack() function:
1
2
3
4
5
6
7
8
9
10
11
12
void DoublyList::insertBack(int elem)
{
	Node *newNode = new Node(elem, last, NULL);

	if (first == NULL)
		first = newNode;
	else
		last->setNext(newNode);

	last = newNode;
	++count;
}



Then this is the Functions.cpp file where I'm having most of my troubles:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include "DoublyList.h"

// overloaded insertion operator
ostream& operator<<(ostream &out, const DoublyList& lst)
{
	if (lst.first == nullptr)
	{
		out << "List is empty" << endl;
	}
	else
	{
		Node* current = lst.first;
		while (current != nullptr)
		{
			out << current->getData() << " ";
			current = current->getNext();
		}
	}

	return out;
}

// copy constructor
DoublyList::DoublyList(const DoublyList& other)
{
	Node* current = other.first;

	while (current != nullptr)
	{
		insertBack(current->getData());
		current = current->getNext();
	}
}


// overloaded assignment operator
DoublyList& DoublyList::operator=(DoublyList lst)
{
	if (first->getData() == lst.first->getData()
		&& last->getData() == lst.last->getData())
	{
		Node* current = first;
		Node* other = lst.first;
		bool same = false;
		while (current != nullptr && !same)
		{
			if (current->getData() == other->getData())
			{
				current = current->getNext();
				other = other->getNext();
			}
			else
			{
				same = true;
			}
		}
		if (same = false)
		{
			cerr << "Attempted assignment to itself" << endl;
		}
	}
	else
	{
		Node* other = lst.first;
		Node* current = first;
		if (first == nullptr)
		{		
			while (other != nullptr)
			{
				insertBack(other->getData());
				other = other->getNext();
			}
		}
		else if (count > lst.count)
		{	
			while (current != nullptr)
			{
				if (other != nullptr)
				{
					current->setData(other->getData());
					other = other->getNext();
					current = current->getNext();
				}
				else
				{
					Node* temp = current;
					current = current->getNext();
					delete temp;
					temp = nullptr;
					--count;
				}
			}
		}
		else if (count == lst.count)
		{
			while (current != nullptr)
			{
				current->setData(other->getData());
				other = other->getNext();
				current = current->getNext();
			}
		}
		else if (count < lst.count)
		{
			while (other != nullptr)
			{
				if (current != nullptr)
				{
					current->setData(other->getData());
					other = other->getNext();
					current = current->getNext();
				}
				else
				{
					insertBack(other->getData());
					other = other->getNext();
				}
			}
		}
		else
		{
			destroyList();
		}
	}

	return *this;
}




This is the DoublyList.cpp:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include "DoublyList.h"

DoublyList::DoublyList()
{
	first = nullptr;
	last = nullptr;
	count = 0;
}

void DoublyList::insertBack(int elem)
{
	Node *newNode = new Node(elem, last, NULL);

	if (first == NULL)
		first = newNode;
	else
		last->setNext(newNode);

	last = newNode;
	++count;
}

void DoublyList::insertBack(const int a[], int numOfElem)
{
	for (int i = 0; i < numOfElem; ++i)
		insertBack(a[i]);
}

int DoublyList::getFirst() const
{
	if (first == nullptr)
		return 0;
	else
		return first->getData();
}

int DoublyList::getLast() const
{
	if (first == nullptr)
		return 0;
	else
		return last->getData();
}

int DoublyList::getNumOfElem() const
{
	return count;
}

Node* DoublyList::getPrevOfFirst() const
{
	if (first == nullptr)
		return 0;
	else
		return first->getPrev();
}

Node* DoublyList::getNextOfLast() const
{
	if (first == nullptr)
		return 0;
	else
		return last->getNext();
}

// getFirstNodeAddress
Node& DoublyList::getFirstNodeAddress() const
{
	return *first; // return the address of the node first is pointing to
}

// getLastNodeAddress
Node& DoublyList::getLastNodeAddress() const
{
	return *last; // return the address of the node last is pointing to
}

void DoublyList::reversePrint() const
{
	if (first == nullptr)
		cout << "List is empty.";
	else
	{
		Node *temp = last;

		while (temp != NULL)
		{
			cout << temp->getData() << " ";
			temp = temp->getPrev();
		}
	}
}

void DoublyList::destroyList()
{
	Node  *temp = first;

	while (first != nullptr)
	{
		first = first->getNext();
		delete temp;
		temp = first;
	}

	last = nullptr;
	count = 0;
}

DoublyList::~DoublyList()
{
	destroyList();
}



And this is the error message I get:
Exception thrown: read access violation.
**this** was 0xFFFFFFFFFFFFFFFF.

This is the Main.cpp (These are just testing cases.I am not allowed to change anything in this file, just to let you guys know what all the files had):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include "DoublyList.h"

#include <iostream>
using namespace std;

//pass by value to preserve original lists
void testCopyConstructor(DoublyList param, int n);
void testOverloadedAssignment(DoublyList calling, DoublyList param, int n);

int main()
{
	int a0[10];
	int a1[20] = { 45 };
	int a2[30] = { 64, 24 };
	int a4[40] = { 13, 54, 12, 34};
	int a7[10] = { 76, 36, 91, 93, 74, 58, 23 };

	DoublyList list0, list1, list2, list4, list7;

	list0.insertBack(a0, 0);
	list1.insertBack(a1, 1);
	list2.insertBack(a2, 2);
	list4.insertBack(a4, 4);
	list7.insertBack(a7, 7);

	cout << "TEST: COPY CONSTRUCTOR" << endl;
	// Copy constructor: calling (empty) - param (empty)
	testCopyConstructor(list0, 1);							// TEST 1
	// Copy constructor: calling (empty) - param (1)
	testCopyConstructor(list1, 2);							// TEST 2
	// Copy constructor: calling (empty) - param (2)
	testCopyConstructor(list2, 3);							// TEST 3
	// Copy constructor: calling (empty) - param (4)
	testCopyConstructor(list4, 4);							// TEST 4
	// Copy constructor: calling (empty) - param (7)
	testCopyConstructor(list7, 5);							// TEST 5

	cout << endl;

	cout << "TEST: OVERLAODED ASSIGNMENT OPERATOR" << endl;
	// Overloaded assignment operator: calling (empty) - param (empty)
	testOverloadedAssignment(list0, list0, 6);								// TEST 6
	// Overloaded assignment operator: calling (empty) - param (1)
	testOverloadedAssignment(list0, list1, 7);								// TEST 7
	// Overloaded assignment operator: calling (empty) - param (2)
	testOverloadedAssignment(list0, list2, 8);								// TEST 8
	// Overloaded assignment operator: calling (empty) - param (4)
	testOverloadedAssignment(list0, list4, 9);								// TEST 9
	// Overloaded assignment operator: calling (empty) - param (7)
	testOverloadedAssignment(list0, list7, 10);								// TEST 10
	// Overloaded assignment operator: calling (1) - param (empty)
	testOverloadedAssignment(list1, list0, 11);								// TEST 11
	// Overloaded assignment operator: calling (1) - param (1)
	testOverloadedAssignment(list1, list1, 12);								// TEST 12
	// Overloaded assignment operator: calling (1) - param (2)
	testOverloadedAssignment(list1, list2, 13);								// TEST 13
	// Overloaded assignment operator: calling (1) - param (4)
	testOverloadedAssignment(list1, list4, 14);								// TEST 14
	// Overloaded assignment operator: calling (1) - param (7)
	testOverloadedAssignment(list1, list7, 15);								// TEST 15
	// Overloaded assignment operator: calling (2) - param (empty)
	testOverloadedAssignment(list2, list0, 16);								// TEST 16
	// Overloaded assignment operator: calling (2) - param (1)
	testOverloadedAssignment(list2, list1, 17);								// TEST 17
	// Overloaded assignment operator: calling (2) - param (2)
	testOverloadedAssignment(list2, list2, 18);								// TEST 18
	// Overloaded assignment operator: calling (2) - param (4)
	testOverloadedAssignment(list2, list4, 19);								// TEST 19
	// Overloaded assignment operator: calling (2) - param (7)
	testOverloadedAssignment(list2, list7, 20);								// TEST 20
	// Overloaded assignment operator: calling (4) - param (empty)
	testOverloadedAssignment(list4, list0, 21);								// TEST 21
	// Overloaded assignment operator: calling (4) - param (1)
	testOverloadedAssignment(list4, list1, 22);								// TEST 22
	// Overloaded assignment operator: calling (4) - param (2)
	testOverloadedAssignment(list4, list2, 23);								// TEST 23
	// Overloaded assignment operator: calling (4) - param (4)
	testOverloadedAssignment(list4, list4, 24);								// TEST 24
	// Overloaded assignment operator: calling (4) - param (7)
	testOverloadedAssignment(list4, list7, 25);								// TEST 25
	// Overloaded assignment operator: calling (7) - param (empty)
	testOverloadedAssignment(list7, list0, 26);								// TEST 26
	// Overloaded assignment operator: calling (7) - param (1)
	testOverloadedAssignment(list7, list1, 27);								// TEST 27
	// Overloaded assignment operator: calling (7) - param (2)
	testOverloadedAssignment(list7, list2, 28);								// TEST 28
	// Overloaded assignment operator: calling (7) - param (4)
	testOverloadedAssignment(list7, list4, 29);								// TEST 29
	// Overloaded assignment operator: calling (7) - param (7)
	testOverloadedAssignment(list7, list7, 30);								// TEST 30

	cout << endl << endl;
	system("Pause");
	return 0;
}

void testCopyConstructor(DoublyList param, int n)
{
	cout << "TEST: " << n << endl;
	cout << "Parameter list: " << param << endl;

	int param_first = param.getFirst();
	int param_last = param.getLast();
	int param_count = param.getNumOfElem();
	Node* param_getPrevOfFirst = param.getPrevOfFirst();
	Node* param_getNextOfLast = param.getNextOfLast();

	DoublyList temp(param);

	cout << "New list (print forward): " << temp << endl;
	cout << "New list (print reverse): ";
	temp.reversePrint();
	if (param_first != temp.getFirst()) cout 
		<< "*** ERROR ***  First node not storing correct value." << endl;
	if (param_last != temp.getLast()) cout 
		<< "*** ERROR ***  Last node not storing correct value. " << endl;
	if (param_count != temp.getNumOfElem()) cout 
		<< "*** ERROR ***  Number of elements is incorrect." << endl;
	if (param_getPrevOfFirst != temp.getPrevOfFirst()) cout 
		<< "*** ERROR ***  Pointer prev of first node is not NULL." << endl;
	if (param_getNextOfLast != temp.getNextOfLast()) cout 
		<< "*** ERROR ***  Pointer next of last node is not NULL." << endl;
	if (param.getNumOfElem() != 0)
	{
		if (param.getFirstNodeAddress() == temp.getFirstNodeAddress()) cout 
			<< "*** ERROR ***  Both lists are pointing to the same first node." << endl;
		if (param.getLastNodeAddress() == temp.getLastNodeAddress()) cout 
			<< "*** ERROR ***  Both lists are pointing to the same first node." << endl;
	}
	
	cout << endl;
}

void testOverloadedAssignment(DoublyList calling, DoublyList param, int n)
{
	cout << "TEST: " << n << endl;
	cout << "Calling list: " << calling << endl; 
	cout << "Parameter list: " << param << endl;

	int calling_first = calling.getFirst();
	int calling_last = calling.getLast();
	int calling_count = calling.getNumOfElem();
	Node* calling_getPrevOfFirst = calling.getPrevOfFirst();
	Node* calling_getNextOfLast = calling.getNextOfLast();

	int param_first = param.getFirst();
	int param_last = param.getLast();
	int param_count = param.getNumOfElem();
	Node* param_getPrevOfFirst = param.getPrevOfFirst();
	Node* param_getNextOfLast = param.getNextOfLast();

	calling = param;

	cout << "... Call overloaded assignment operator... calling = param" << endl;
	cout << "Calling list (print forward): " << calling << endl;
	cout << "Parameter list (print forward): " << param << endl;
	cout << "Calling list (print reverse): ";
	calling.reversePrint();
	cout << endl;
	cout << "Parameter list (print reverse): ";
	param.reversePrint();
	cout << endl;

	if (param_first != calling.getFirst()) cout 
		<< "*** ERROR ***  First node not storing correct value. (Test " << n << ")" << endl;
	if (param_last != calling.getLast()) cout 
		<< "*** ERROR ***  Last node not storing correct value. (Test " << n << ")" << endl;
	if (param_count != calling.getNumOfElem()) cout 
		<< "ERROR: Number of elements is incorrect. (Test " << n << ")" << endl;
	if (param_getPrevOfFirst != calling.getPrevOfFirst()) cout 
		<< "ERROR: Pointer prev of first node is not NULL. (Test " << n << ")" << endl;
	if (param_getNextOfLast != calling.getNextOfLast()) cout 
		<< "ERROR: Pointer next of last node is not NULL. (Test " << n << ")" << endl;
	if (param.getNumOfElem() != 0)
	{
		if (calling.getFirstNodeAddress() == param.getFirstNodeAddress()) cout 
			<< "ERROR: Both lists are pointing to the same first node. (Test " << n << ")" << endl;
		if (calling.getLastNodeAddress() == param.getLastNodeAddress()) cout 
			<< "ERROR: Both lists are pointing to the same first node. (Test " << n << ")" << endl;
	}

	cout << endl;
}

Topic archived. No new replies allowed.