Linker Errors? Maybe...

Hello everyone, I am having a really hard time instantiating my objects. In the following program I need to implement an output using contents of the pointers and member functions. I will put the code(three files) followed by the error log. Any help you can give is appreciated(explaining the errors, accessing objects, etc.).

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
//ListP.h

typedef char ListItemType;

//ADT list -Pointer-based implementation
class List
{
public:
//Constructors and destructors

	//Default Constructor
	List();

	//Copy Constructor
	//@param aList The list to copy
	List(const List& aList);

	//Destructor
	~List();

	//List operations
	bool isEmpty() const;
	int getLength() const;
	void insert(int index, const ListItemType& newItem);
	void remove(int index);
	void retrieve(int index, ListItemType& dataItem) const;

private:
	struct ListNode //A node on the list.
	{
		ListItemType item; //A data item on the list
		ListNode *next; //Pointer to next node
	};//end ListNode

	int size; //Number of items in list.
	ListNode *head; //Ponter to linked list of items.

	ListNode *find(int index) const;
};//endList
//End of header file. 


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
//ListP.cpp

#include <cstddef> //for NULL
#include <new> // for bad_alloc
#include "ListP.h" // header file
#include <iostream>

using namespace std;

//definitions of methods follow;

//default constructor
List::List() : size(0), head(NULL)
{
}//end default constructor

//List yourList(myList);

List::List(const List& aList)
	: size(aList.size)
{
	if (aList.head == NULL)
		head = NULL; //original list is empty

	else
	{ //copy first node
		head = new ListNode;
		head->item = aList.head->item;

		//copy rest of list
		ListNode *newPtr = head; //new list pointer

		for(ListNode *origPtr = aList.head->next;
			origPtr != NULL;
			origPtr = origPtr->next)
		{ newPtr->next = new ListNode;
		newPtr = newPtr->next;
		newPtr->item = origPtr->item;
		}//end for

		newPtr->next = NULL;
	}//end if
}//end copy constructor

//destructor
List::~List()
{
	while (!isEmpty())
		remove(1);
}//end destructor

bool List::isEmpty() const
{
	return size == 0;
}//end isEmpty

int List::getLength() const
{
	return size;
}//end getLength

List::ListNode *List::find(int index) const
{
	if((index < 1) || (index > getLength()))
		return NULL;

	else //count from the beginning of the list
	{ ListNode *cur = head;
	for(int skip = 1; skip < index; ++skip)
		cur = cur->next;
	return cur;
	}//end if
}//end find

void List::retrieve(int index, ListItemType& dataItem) const
{
	if ((index < 1) || (index > getLength()))
		cout << "Index out of range.";
	else
	{//get pointer to node, then data in node
		ListNode *cur = find(index);
		dataItem = cur->item;
	}//end if
}//end retrieve

void List::insert(int index, const ListItemType& newItem)
{
	int newLength = getLength() + 1;

	if ((index < 1) || (index > newLength))
		cout << "Index out of range.";
	else
	{//create new node and place newItem in it
			ListNode *newPtr = new ListNode;
			size = newLength;
			newPtr->item = newItem;

			//Attach new node to list.
			if (index == 1)
			{//insert new node at beginning of list.
				newPtr->next = head;
				head = newPtr;
			}
			else
			{	ListNode *prev = find(index - 1);
				//insert new node after node to which prev points.
				newPtr->next = prev->next;
				prev->next = newPtr;
			}//end if
	}//end if
}//end insert

void List::remove(int index)
{
	ListNode *cur;

	if(index < 1 || (index > getLength()))
		cout << "Index out of range.";
	else
	{ --size;
	if(index == 1)
	{//delete the first node from the list
		cur = head; //save pointer to node
		head = head->next;
	}

	else
	{ListNode *prev = find(index-1);
	//delete the node after the node to which prev points
	cur = prev->next; //save pointer to node
	prev->next = cur->next;
	}//end if
	
	//return node to system
	cur->next = NULL;
	delete cur;
	cur = NULL;
	}//end if
}//end remove 


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
//test.cpp
//implementation of objects

#include "ListP.cpp"
#include <iostream>

using namespace std;

int main ()
{
	//List list = ('h', 'e', 'l', 'l', 'o');

	//List L1 = list;
	List();
	List(L1);
	char insertItem = 'h';
	char retrieveItem = 'i';
	//L1 = ('h', 'e', 'l', 'l', 'o');

	L1.retrieve(1, retrieveItem);
	L1.insert(1, insertItem);
	L1.remove(1);

	cout << "GAH!!" << endl;


	system("pause");
	return 0;
}


Here are the errors:

1>------ Build started: Project: ComSci2Project2, Configuration: Debug Win32 ------
1>Build started 2/12/2012 6:00:39 PM.
1>InitializeBuildStatus:
1> Touching "Debug\ComSci2Project2.unsuccessfulbuild".
1>ClCompile:
1> ListP.cpp
1> Generating Code...
1> Skipping... (no relevant changes detected)
1> test.cpp
1>ManifestResourceCompile:
1> All outputs are up-to-date.
1>test.obj : error LNK2005: "public: __thiscall List::List(void)" (??0List@@QAE@XZ) already defined in ListP.obj
1>test.obj : error LNK2005: "public: __thiscall List::List(class List const &)" (??0List@@QAE@ABV0@@Z) already defined in ListP.obj
1>test.obj : error LNK2005: "public: __thiscall List::~List(void)" (??1List@@QAE@XZ) already defined in ListP.obj
1>test.obj : error LNK2005: "public: bool __thiscall List::isEmpty(void)const " (?isEmpty@List@@QBE_NXZ) already defined in ListP.obj
1>test.obj : error LNK2005: "public: int __thiscall List::getLength(void)const " (?getLength@List@@QBEHXZ) already defined in ListP.obj
1>test.obj : error LNK2005: "private: struct List::ListNode * __thiscall List::find(int)const " (?find@List@@ABEPAUListNode@1@H@Z) already defined in ListP.obj
1>test.obj : error LNK2005: "public: void __thiscall List::retrieve(int,char &)const " (?retrieve@List@@QBEXHAAD@Z) already defined in ListP.obj
1>test.obj : error LNK2005: "public: void __thiscall List::insert(int,char const &)" (?insert@List@@QAEXHABD@Z) already defined in ListP.obj
1>test.obj : error LNK2005: "public: void __thiscall List::remove(int)" (?remove@List@@QAEXH@Z) already defined in ListP.obj
1>C:\Users\Josh\Documents\Visual Studio 2010\Projects\ComSci2Project2\Debug\ComSci2Project2.exe : fatal error LNK1169: one or more multiply defined symbols found
1>
1>Build FAILED.
1>
1>Time Elapsed 00:00:01.28
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
Last edited on

Hi

First you should not include source file in your application, so this is wrong-> #include "ListP.cpp" , but you should include header file true -> #include "ListP.h"

When you post your code first post the header file and than the source...

what is your aim to call the constructor on line 14 List(); ??
and where do you declare L1 which you pass it unto copy-constructor on line 15 List(L1); ?

It is also recommended to have two version of methods such as , size, isEmpty and so on...

in this way

1
2
3
4
5
bool isEmpty();
bool isEmpty() const;

int getLength():
int getLength() const;



It is also better if you declare ListNode outside of your class, for better control.

and finally include file in following way

1
2
3
4
5
#include <iostream>
#include <cstddef> //for NULL
#include <new> // for bad_alloc

#include "ListP.h" // header file not first 


Last edited on
Including the ListP.h rather than the ListP.cpp in the test.cpp file resolved the errors I was receiving from the compiler(thanks for that). I will also remember the proper order in which to post my code for next time. Anyway..

Everything in the test.cpp file is just a poor attempt to access the objects for implementation. Unfortunately my Computer Science I class did not even get to structures so I have been trying to teach myself(incorrectly obviously) how to implement these objects. If you could give me an example for me to study that would help me understand what is actually necessary to get some output(maybe a list of characters?).

From what I have read I assume that have a second version of the methods is used to prevent corrupting the original data?

[Edit] The plan for the test.cpp was to initialize the list as characters, run the list through each process(insert, retrieve, remove) and display the output in between each process. I was trying to display something like this:

hello
hhello
h
hello
Last edited on
Hi, try to change this part of code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
List::List(const List& aList):size(aList.size){
    if (aList.isEmpty()){
                size=0;
		head = NULL; //original list is empty
    }else{
        size=aList.size;
	ListNode *pNode=aList.head;
        ListNode **auxHead= &head;
        do{
            (*auxHead)=new ListNode;
            (*auxHead)->item=pNode->item;
            auxHead = &(*auxHead)->next
            pNode=pNode->next;
        }while(pNode != NULL);
        (*auxHead)->next = NULL;
    }
}//end copy constructor  
Last edited on
Okay, this works fine but my main focus is on the test.cpp could you show me how to properly make use of one of the objects? For example outputting a character array and inserting a new variable?
I have made changes to test.cpp and I can see now that size is increasing so there should be data within the list. I am still not sure how I can display the list in the output though. Any ideas?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include "ListP.h"
#include <iostream>

using namespace std;

int main ()
{
	List L1;

	//L1.retrieve(1, retrieveItem);
	L1.insert(1, 'O');
	L1.insert(1, 'L');
	L1.insert(1, 'L');
	L1.insert(1, 'E');
	L1.insert(1, 'H');

	L1.remove(1);

	cout << "This should display the list" << endl;


	system("pause");
	return 0;
}


[Edit] I'm wondering if I could write a loop that will display the initial pointer and increase it's index by one.
Last edited on
you can overload the 'operator<<' in this way:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

// this into the class definition

friend ostream& operator<<(ostream& out,const List& list);

// this the implementation

ostream& operator<<(ostream& out,const List& list){
    ListNode *pHead=list.head;
    while(pHead != NULL){
        cout<<pHead->item;
        pHead=pHead->next;
    }
    return out;
}
I figured it out, thanks for the help everyone.
Topic archived. No new replies allowed.