Quantcast
Channel: Programming Forums
Viewing all articles
Browse latest Browse all 51036

Creating & Implementing Constructors & Overloaded Operators

$
0
0
Hello; I apologize in advance for the hefty amount of code I'll be posting, but I do believe that it's necessary to see it all in order to understand where I'm coming from. Essentially, this program is a basic doubly linked list (it doesn't have anything to do with templates, so please refrain from mentioning templates in your responses); I want to add a copy constructor, destructor, overloaded + operator, overloaded - operator, and overloaded = assignment operator to the program. For those who are curious, the overloaded + & - operators will be used to either add or delete nodes to/from this doubly linked list. I've included my thought processes and inquiries in the code comments. Overall, I want to figure out how to properly implement these functions for a doubly linked list. I've seen plenty of examples where strings and arrays are used, but those don't seem to transition well when referring to linked lists. In particular, I'd like to know where my errors specifically are and suggestions on how to correct them as necessary. If possible, I'd like examples of code with your responses rather than statements alone; in my experience, most people are a little too vague if they only respond with text instead of displaying any references to code examples. Thank you all for your time!


Structure File:
#ifndef _sListNode
#define _sListNode

typedef struct sListNode 
{
	int value;
	sListNode *Next, *Pre; //A node can point to the node in front of it or after it
	sListNode(int x)
	{
		value = x;
		Next = NULL; 
		Pre = NULL;
	};
	sListNode() : value(0) {};
} MyNode; //MyNode is the standard sListNode for implementation

#endif




Class File:
#include "Node Structure.h" //The sListNode is utilized here,

class doublyLinkedList
{
public:
	doublyLinkedList();
	doublyLinkedList(int);
	doublyLinkedList(const doublyLinkedList&);
	~doublyLinkedList();

	void Add(int);
	void Delete(int);
	void ShowNodes();

	doublyLinkedList operator+(const doublyLinkedList&);
	doublyLinkedList operator-(const doublyLinkedList&);
	doublyLinkedList& operator=(const doublyLinkedList&);

private:
	MyNode *front;
	MyNode *back;
};




Class Function Implementations:
#include <iostream>
#include "Node Class.h"

using namespace std;

doublyLinkedList::doublyLinkedList()
{
	cout << "Construction in progress...\n";
	front = NULL;
	back = NULL;
}


doublyLinkedList::doublyLinkedList(int initial) //Possible alternate constructor for a node (unfinished)
{
	cout << "Construction in progress...\n";
	front = new MyNode(initial);
	back = NULL;
}

doublyLinkedList::doublyLinkedList(const doublyLinkedList& object)
{
	front = NULL; //front is made NULL to have room to copy in the header node from the class parameter.
	MyNode *copy = object.front;

	while(copy != NULL) //copy shouldn't be NULL until object is NULL
	{
		Add(copy->value); //Each value of object should be reproduced in copy.
		copy = copy->Next; //copy should keep pointing to allow for more nodes in the list
		//Why the values are printed backwards (ie 5, 2 becomes 2, 5) is beyond me...
	}
}

doublyLinkedList::~doublyLinkedList()
{
	cout << "Destruction in progress...\n";

	MyNode *Header = front;
	MyNode *removeTemp;

	while(Header != NULL)
	{
		removeTemp = Header->Next;
		delete Header; //The nodes are removed from the list one at a time from front to back.
		Header = removeTemp;
	}
}

void doublyLinkedList::Add(int num)
{
	MyNode *n = new MyNode(num);

	if(front == NULL) //The added number becomes the head & end if the list is empty.
	{
		front = n; 
		back = n;
	}
	else
	{
		front->Pre = n; //The added number is routed before the current header...
		n->Next = front; //...and placed in the (NULL) space before the current header.
		front = n;
	}

	cout << "The number " << num << " was added to the front of our linked list.\n";
}

void doublyLinkedList::Delete(int num)
{
	MyNode *Current = front;

	while(Current != NULL && Current->value != num)
	{
		Current = Current->Next; //Current will cycle through until it finds the number to be deleted.
	}

	if(Current != NULL)
	{
		if(Current == front)
		{
			front = Current->Next; //If the header is deleted, the number after it becomes the new header.
		}
		else if(Current == back)
		{
			back = Current->Pre;
			Current->Pre->Next = NULL; //When the last node is deleted, the space it occupied MUST be set to NULL.
		}
		else if((Current == front) && (Current == back)) //If the only node in the list is deleted, both of its pointers must be set to NULL.
		{
			front = Current->Next;
			Current->Next->Pre = NULL;
			back = Current->Pre;
			Current->Pre->Next = NULL;
		}
		else
		{
			Current->Pre->Next = Current->Next; //If a node in the middle of the list is deleted, both pointers 
			Current->Next->Pre = Current->Pre;  //to it must be rerouted over the now discarded space.
		}

		delete Current;

		cout << "The number " << num << " was found and removed from our linked list.\n";
		}
	else
	{
		cout << "The number " << num << " was not found in our linked list.\n";
	}
}


void doublyLinkedList::ShowNodes()
{
	MyNode *tempNode = front;

	while(tempNode != NULL)
	{
		cout << tempNode->value << " ";
		tempNode = tempNode->Next;
	}

	cout << endl;
}


doublyLinkedList doublyLinkedList::operator+(const doublyLinkedList& addThis)
{
	doublyLinkedList thisNode;
	thisNode = *this;

	thisNode.Add(addThis.front->value); //I can only access a set value to execute 'Add' correctly by using the value pointed
										//to at the front of thisNode. This is because I have MyNode pointers for front & back, 
										//but I'm not sure how to access values in the middle of the list.

	return thisNode;
}

doublyLinkedList doublyLinkedList::operator-(const doublyLinkedList& removeThis)
{
	doublyLinkedList thisNode;
	thisNode = *this;

	thisNode.Delete(removeThis.front->value); //This is where the problem is even more obvious. I want to access more than just the
											  //first value in the list to be removed, but I'm not sure how I could fashion some 
											  //pointer--say, removeThis.mid->value, with mid being a pointer that could somehow step
											  //through a list until it finds the given value and deletes it.

	return thisNode;
}

doublyLinkedList& doublyLinkedList::operator=(const doublyLinkedList& thisList)
{
	if(this == &thisList)
	{
		return *this; //If the node on the left side equals the node on the right side, it should just return itself.
	}

	while(front != NULL) //If the node on the left side doesn't equal the node on the right side, it should empty itself.
	{
		MyNode *removeTemp = front->Next;
		delete front; //Granted, am I just calling the destructor with this?
		front = removeTemp;
	} //By the end of all of this, I should have an empty list on the left side of the = operator.

	MyNode *Current = thisList.front; //Now, the equalizing process works in a similar manner to the copy constructor.

	while(Current != NULL) //The new list takes on the header value of the thisList parameter...
	{
		Add(Current->value); //adds its values accordingly...
		Current = Current->Next; //and keeps cycling through the whole list.
	}

	front = Current; //To be honest, it was recommended that I include this, but I'm not entirely sure what purpose it serves...

	return *this;
}




Main File:
#include <iostream>
#include "Node Class.h"

using namespace std;

int main()
{
	doublyLinkedList DLL;

	DLL.ShowNodes();
	DLL.Add(2);
	DLL.ShowNodes();
	DLL.Add(5);
	DLL.ShowNodes();

	doublyLinkedList DLL2(DLL);

	DLL.Add(8);
	DLL.ShowNodes();
	DLL.Add(7);
	DLL.ShowNodes();
	DLL.Delete(1);
	DLL.ShowNodes();
	DLL.Add(3);
	DLL.ShowNodes();
	DLL.Delete(5);
	DLL.ShowNodes();
	DLL.Delete(2);
	DLL.ShowNodes();
	DLL.Delete(3);
	DLL.ShowNodes();
	DLL = DLL - 8;
	DLL.ShowNodes();
	DLL.Delete(7);
	DLL.ShowNodes();
	DLL = DLL + 1;
	DLL.ShowNodes();

	cout << "The following nodes are in the copied doubly linked list:\n";
	DLL2.ShowNodes();

	system("pause");

	return 0;
}




In case anyone is curious, the most notable run-time error I encounter is with the = assignment operator. It consistently calls both the constructor & destructor but doesn't supply any output.

Viewing all articles
Browse latest Browse all 51036

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>