Problem initializing templatized class (urgent)

I'm currently trying to test out a standard simple linked list class. I'm currently trying to templatize the class for ints/chars, then going to move on to templatizing it for a struct. The current driver is simply to ensure that I can create an object and get an item in there, then remove it successfully:

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
#include <iostream>
using namespace std;

#ifndef CSIMPLELIST_H
#define CSIMPLELIST_H
#include "CSimpleList.h"
#endif //CSIMPLELIST_H


int		main(void)
{
	auto	CSimpleList<char>	charObj;
        ERROR: Expected initializer before '<' token 

	auto	CSimpleList<int>	intObj;
        ERROR: Expected initializer before '<' token 

	auto	char				inChar = 'y';
	auto	int					inInt = 1;
	
	cout << "Number of items in charObj: " << charObj.m_numItems << endl;
        ERROR: 'charObj' was not declared in this scope 

	cout << "Number of items in intObj: " << intObj.m_numItems << endl;
        ERROR: 'intObj' was not declared in this scope 

	
	charObj.InsertItem(inChar, 1);
	intObj.InsertItem(inInt, 1);
	
	cout << "New number of items in charObj: " << charObj.m_numItems << endl;
	cout << "New number of items in intObj: " << intObj.m_numItems << endl;
	
	charObj.RemoveItem(1);
	intObj.RemoveItem(1);
	
	cout << "Final number of items in charObj: " << charObj.m_numItems << endl;
	cout << "Final number of items in intObj: " << intObj.m_numItems << endl;	
	
	return 0;
}



the redundant ifndef/endif is because I was getting a redefinition error, even though I have the safeguard in my .h file.

I'd appreciate any help I could get. I'll probably have more questions as this is just the basis for a VERY large project (relative to anything I've dealt with before) I'm working on.


I can provide the .h file upon request if that would be helpful in finding a solution.
Last edited on
Post the .h file - it's probably not setup correctly.

BTW - What's with the auto keyword?

auto just means the variable is to be initialized off the stack. I'm aware it's not required.

Here's the 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
#ifndef CSIMPLELIST_H
#define CSIMPLELIST_H


// linked list structure
template<typename Type>
struct  LNode
{
    Type			item;
    LNode<Type>		*next;
	
};

// trivial exception class for CSimpleList
class   CListEx
	{
	};

// class declaration
template <class Type>
class   CSimpleList
	{
	public: 
		// constructors
		CSimpleList(void) : m_headPtr(0), m_numItems(0) {}
		CSimpleList(const CSimpleList  &object);
		~CSimpleList(void) { DestroyList(); }
		
		// other member functions
		void    CreateList(void);
		int     DestroyList(void);
		void    GetListItem(int  index, Type  &item) const ;
		int     GetNumItems(void) const { return (m_numItems); }
		void    InsertItem(Type  newItem, int  index);
		bool    IsListEmpty(void) const { return (0 == m_numItems); }
		void    RemoveItem(int  index);
		
		// overloaded operators
		CSimpleList&    operator=(const CSimpleList<Type>  &rhs);
		
                // this is here for testing purpouses only, will be in private section 
		int          m_numItems;
		
	private:
		// data members
		LNode<Type>		*m_headPtr;
		//int				m_numItems;
		
		// member functions
		int				CopyList(const CSimpleList<Type>  &otherList);
		LNode<Type>*	GetNodePtr(int  index) const;
	};


#include "CSimpleList.cpp"

#endif  // CSIMPLELIST_H 
Last edited on
The first "guard" defines CSIMPLELIST_H. Then it is defined and the second guard doesn't include it anymore. Therefore it isn't included at all, and CSimpleList doesn't name a type when used.
#include "CSimpleList.cpp"
That's your problem. Don't ever #include .cpp files. The whole template code goes into the .h file (or, if you use the explicit instantiation approach, into another .h file, or, if you use the export keyword, into an .cpp file which isn't included in any .h file).

The auto keyword is, by the way, redundant and no C++ programmer who is in some definition sane uses it. Furthermore it seems as if the keyword will have a new meaning in the upcoming standard "C++0x" (which, given the otherwise embraced backward compatibility, shows that nobody considered to be a C++ programmer by the standards committee uses it), so I strongly suggest that you avoid its usage.
That's exactly how our instructor and book show how to implement a templatized class. If I take off the ifndef/endif around the #include "CSimpleList.h" in main, it gives me a redefinition error on all functions. Also, the reason we use auto is because our instructor requests it. I'm sure once I get coding myself, I won't include the redundant code.

How would you suggest getting this to work? I initialized my CSimpleList object with their respecitve template type args. I don't understand what I have done wrong here. This is my 3rd semester in lower level classes, currently in C++ data structures. Thanks in advance for further claification.
You've got circular includes bud.
Yout should never, ever have an #include "*.cpp"
ever.
Took it out, still have the redefinition errors :( this sucks - this is the smallest of 4 classes I need to get ready and I'm still hung up on this. I just can't figure it out. Futher help greatly appreciated.

Edit: fiddled with it a lil and now i'm getting errors like this:

"CSimpleList<int>::InsertItem(int, int)", referenced from:
_main in main.o


"CSimpleList<int>::RemoveItem(int)", referenced from:
_main in main.o


for every function call in main. I know my instructor taught us to write a templatized class header the way i originally did for a reason... i just don't know why no one here knows the reason.
Last edited on
Really this should be quite straight forward.
I think you getting all confused about inclusions of header files, etc.

have you got csimplelist.cpp handy?

Like exception says - the #include Csimplelist.cpp statement should not be in the csimplelist.h file.


Post the csimplelist.cpp file - this should not be giving this much problem.
Last edited on
Here's the .cpp file. The change I made to the .h file was just taking out the #include of the cpp file. The is pretty large and the comments have yet to be updated. The code is where I believe it should be though. Thank you for taking a look at it.

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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
#include    <iostream>
using   namespace   std;
#include "CSimpleList.h"



// ==== CSimpleList ===========================================================
// 
// This copy constructor makes a copy of the object provided by the caller,
// node for node.
//
// Input:
//		&otherList	--	a const reference to the caller's CSimpleList object to
//						be copied.
//
// Output:
//		If all goes well, a copy of the user's CSimpleList object is created
//		and the number of nodes copied is returned to the caller.
//
// ============================================================================

template<typename Type>
CSimpleList<Type>::CSimpleList(const CSimpleList<Type>  &object)
{
	m_numItems = 0;
	m_headPtr = NULL;
	CopyList(object);
	
} // end of "CSimpleList"



// ==== CreateList ============================================================
// 
// This function creates an empty list.
//
// Input:
//		None.
//
// Output:
//		An empty list is created and a return value of LIST_SUCCESS is returned
//      to the caller if all goes well.
//
// ============================================================================

template<typename Type>
void        CSimpleList<Type>::CreateList(void)
{
    // destroy list in case there is a pre-existing list
    DestroyList();
    
    // null headPtr and zero numItems then return success
    m_numItems = 0;
    m_headPtr = NULL;
    return;
	
} // end of "CreatList"



// ==== DestroyList ===========================================================


template<typename Type>
int         CSimpleList<Type>::DestroyList(void)
{
    auto    int     index = NULL;
    
    // free all nodes in the list
    for (index = 0; index < m_numItems; index++)
    {
        RemoveItem(index);
    }
    
    // zero out data members and return
    m_numItems = 0;
    m_headPtr = NULL;
    return index;
	
} // end of "DestroyList"



// ==== GetListItem ===========================================================


template<typename Type>
void        CSimpleList<Type>::GetListItem(int  index, Type  &item) const 
{
    auto    LNode<Type>           *nodePtr = NULL;
    
    // check for empty list
    if (true == IsListEmpty())
    {
        //throw CListEx(LIST_EMPTY);
		cout << "Error: GetListItem" << endl;
		return;
    }
    
    if (NULL == (nodePtr = GetNodePtr(index)))
    {
        // throw exception if invalid index is provided
        //throw CListEx(INVALID_INDEX);
		cout << "Error: GetListItem" << endl;
		return;
    }
    
    // else set item equal to value in corresponding LNode and return success
    else
    {
        item = nodePtr->item;
    }
    
} // end of "GetListItem"



// ==== InsertItem ============================================================


template<typename Type>
void        CSimpleList<Type>::InsertItem(Type  newItem, int  index)
{
	auto	LNode<Type>		*nodePtr = NULL;
	auto	LNode<Type>		*prevPtr = NULL;
	
	// if item is to be inserted into front of the list
    if (0 == index)
	{
		nodePtr = new LNode<Type>;
		nodePtr->item = newItem;
		nodePtr->next = m_headPtr;
		m_headPtr = nodePtr;
		m_numItems++;
		return;
	}
	
	// else if item is to be inserted into end of the list, do so
	else if (m_numItems == index)
	{
		nodePtr = GetNodePtr(index - 1);
		nodePtr->next = new LNode<Type>;
		nodePtr->next->item = newItem;
		nodePtr->next->next = NULL;
		m_numItems++;
		return;
	}
	
	// else handle insertion into middle of the list
	else if ((index < m_numItems) && (index > 0))
	{
		nodePtr = new LNode<Type>;
		nodePtr->item = newItem;
		nodePtr->next = GetNodePtr(index);
		prevPtr = GetNodePtr(index - 1);
		prevPtr->next = nodePtr;
		m_numItems++;
		return;
	}
	
	// else throw exception due to invalid index
	else
	{
	    //throw CListEx(INVALID_INDEX);
		cout << "Error: InsertItem" << endl;
		return;
	}
	
} // end of "InsertItem"



// ==== RemoveItem ============================================================
// 
// This function removes an item at target index location.
//
// Input:
//		index	--	an int storing the index to the node the caller wants to
//					remove.
//
// Output:
//
// ============================================================================

template<typename Type>
void        CSimpleList<Type>::RemoveItem(int  index)
{
    auto    LNode<Type>		*nodePtr = NULL;
    auto    LNode<Type>		*tempPtr = NULL;
    
    // if the list is empty, throw an exception
    if (true == IsListEmpty())
    {
        //throw CListEx(LIST_EMPTY);
		cout << "Error: RemoveItem: " << endl;
		return;
    }
    
    // get pointer for zero-based node to be removed
    nodePtr = GetNodePtr(index);
    
    // if invalid pointer is returned, throw error
    if (NULL == nodePtr)
    {
        //throw CListEx(INVALID_INDEX);
		cout << "Error: RemoveItem: " << endl;
		return;
    }
    
    // else remove that item
    else
    {
        tempPtr = GetNodePtr(index - 1);
        
        // handle removal from head of the list
        if (NULL == tempPtr)
        {
            m_headPtr = nodePtr->next;
            delete nodePtr;
            m_numItems--;
        }
        
        // else remove item from the middle/end of the list
        else
        {
            tempPtr->next = nodePtr->next;
            delete nodePtr;
            m_numItems--;
        }
    }
	
    return;
	
} // end of "RemoveItem"



// ==== CopyList ==============================================================


template<typename Type>
int             CSimpleList<Type>::CopyList(const CSimpleList<Type>  &otherList)
{
	auto	int		index;
	auto	Type	otherItem;
	
	DestroyList();
	CreateList();
	m_numItems = otherList.m_numItems;
	
	for (index = 0; index < m_numItems; index++)
	{
	    otherList.GetListItem(index, otherItem);
		InsertItem(index, otherItem); 
	}
	
	return index;
	
} // end of "CopyList"



// ==== GetNodePtr ============================================================
// 
// This function is used to gain indexed access into the linked list.  If an
// invalid index is provided (beyond the allocated amount of nodes), a NULL
// pointer is returned.
//
// Input:
//		index	--	an int storing the index to the node the caller wants a
//					pointer to.
//
// Output:
//		If a valid index is provided, a reference to the LNode at the caller's
//		index is returned, otherwise a NULL pointer is returned.
//
// ============================================================================

template<typename Type>
LNode<Type>*          CSimpleList<Type>::GetNodePtr(int  index) const
{
    auto    LNode<Type>		*leadPtr = m_headPtr;
    auto    int				counter;
    
    // if invalid (negative index) is provided, return null
    if (index < 0)
    {
        return NULL;
    }
    
    // index through the array until either target index or end of list is
    // reached
    for (counter = 0; ((counter < index) && (leadPtr != NULL)); counter++)
    {
        leadPtr = leadPtr->next;
    }
    
    // leadPtr now contains either a pointer to the target LNode or NULL, so
    // return leadPtr
    return leadPtr;
	
} // end of "GetNodePtr;



// ==== operator= =============================================================


template<typename Type>
CSimpleList<Type>&    CSimpleList<Type>::operator=(const CSimpleList<Type>  &rhs)
{
	if (this != &rhs)
	{
		CopyList(rhs);
	}
	
	return *this;	
} // end of "operator=" 
OK - here goes.
1. Combine the CSimpleList.cpp and CSimpleList.h into one file (Csimplelist.h).
2. Get rid of the iifdefs etc from the main file - so you have just two files like this:

(I'll have to make two posts)


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
#include <iostream>


#include "CSimpleList.h"

using namespace std;


int		main(void)
{
		CSimpleList<char>	charObj;

		CSimpleList<int>	intObj;

		char				inChar = 'y';
		int					inInt = 1;
	
	cout << "Number of items in charObj: " << charObj.m_numItems << endl;

	cout << "Number of items in intObj: " << intObj.m_numItems << endl;

	
	charObj.InsertItem(inChar, 1);
	intObj.InsertItem(inInt, 1);
	
	cout << "New number of items in charObj: " << charObj.m_numItems << endl;
	cout << "New number of items in intObj: " << intObj.m_numItems << endl;
	
	charObj.RemoveItem(1);
	intObj.RemoveItem(1);
	
	cout << "Final number of items in charObj: " << charObj.m_numItems << endl;
	cout << "Final number of items in intObj: " << intObj.m_numItems << endl;	
	
	return 0;
}



The new and improved CSimplelist.h
(So now there is no simplelist.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
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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
#ifndef CSIMPLELIST_H
#define CSIMPLELIST_H


// linked list structure
template<typename Type>
struct  LNode
{
    Type			item;
    LNode<Type>		*next;
	
};

// trivial exception class for CSimpleList
class   CListEx
	{
	};

// class declaration
template <class Type>
class   CSimpleList
	{
	public: 
		// constructors
		CSimpleList(void) : m_headPtr(0), m_numItems(0) {}
		CSimpleList(const CSimpleList  &object);
		~CSimpleList(void) { DestroyList(); }
		
		// other member functions
		void    CreateList(void);
		int     DestroyList(void);
		void    GetListItem(int  index, Type  &item) const ;
		int     GetNumItems(void) const { return (m_numItems); }
		void    InsertItem(Type  newItem, int  index);
		bool    IsListEmpty(void) const { return (0 == m_numItems); }
		void    RemoveItem(int  index);
		
		// overloaded operators
		CSimpleList&    operator=(const CSimpleList<Type>  &rhs);
		
                // this is here for testing purpouses only, will be in private section 
		int          m_numItems;
		
	private:
		// data members
		LNode<Type>		*m_headPtr;
		//int				m_numItems;
		
		// member functions
		int				CopyList(const CSimpleList<Type>  &otherList);
		LNode<Type>*	GetNodePtr(int  index) const;
	};


// ==== CSimpleList ===========================================================
// 
// This copy constructor makes a copy of the object provided by the caller,
// node for node.
//
// Input:
//		&otherList	--	a const reference to the caller's CSimpleList object to
//						be copied.
//
// Output:
//		If all goes well, a copy of the user's CSimpleList object is created
//		and the number of nodes copied is returned to the caller.
//
// ============================================================================

template<typename Type>
CSimpleList<Type>::CSimpleList(const CSimpleList<Type>  &object)
{
	m_numItems = 0;
	m_headPtr = NULL;
	CopyList(object);
	
} // end of "CSimpleList"



// ==== CreateList ============================================================
// 
// This function creates an empty list.
//
// Input:
//		None.
//
// Output:
//		An empty list is created and a return value of LIST_SUCCESS is returned
//      to the caller if all goes well.
//
// ============================================================================

template<typename Type>
void        CSimpleList<Type>::CreateList(void)
{
    // destroy list in case there is a pre-existing list
    DestroyList();
    
    // null headPtr and zero numItems then return success
    m_numItems = 0;
    m_headPtr = NULL;
    return;
	
} // end of "CreatList"



// ==== DestroyList ===========================================================


template<typename Type>
int         CSimpleList<Type>::DestroyList(void)
{
    auto    int     index = NULL;
    
    // free all nodes in the list
    for (index = 0; index < m_numItems; index++)
    {
        RemoveItem(index);
    }
    
    // zero out data members and return
    m_numItems = 0;
    m_headPtr = NULL;
    return index;
	
} // end of "DestroyList"



// ==== GetListItem ===========================================================


template<typename Type>
void        CSimpleList<Type>::GetListItem(int  index, Type  &item) const 
{
    auto    LNode<Type>           *nodePtr = NULL;
    
    // check for empty list
    if (true == IsListEmpty())
    {
        //throw CListEx(LIST_EMPTY);
		cout << "Error: GetListItem" << endl;
		return;
    }
    
    if (NULL == (nodePtr = GetNodePtr(index)))
    {
        // throw exception if invalid index is provided
        //throw CListEx(INVALID_INDEX);
		cout << "Error: GetListItem" << endl;
		return;
    }
    
    // else set item equal to value in corresponding LNode and return success
    else
    {
        item = nodePtr->item;
    }
    
} // end of "GetListItem"



// ==== InsertItem ============================================================


template<typename Type>
void        CSimpleList<Type>::InsertItem(Type  newItem, int  index)
{
	auto	LNode<Type>		*nodePtr = NULL;
	auto	LNode<Type>		*prevPtr = NULL;
	
	// if item is to be inserted into front of the list
    if (0 == index)
	{
		nodePtr = new LNode<Type>;
		nodePtr->item = newItem;
		nodePtr->next = m_headPtr;
		m_headPtr = nodePtr;
		m_numItems++;
		return;
	}
	
	// else if item is to be inserted into end of the list, do so
	else if (m_numItems == index)
	{
		nodePtr = GetNodePtr(index - 1);
		nodePtr->next = new LNode<Type>;
		nodePtr->next->item = newItem;
		nodePtr->next->next = NULL;
		m_numItems++;
		return;
	}
	
	// else handle insertion into middle of the list
	else if ((index < m_numItems) && (index > 0))
	{
		nodePtr = new LNode<Type>;
		nodePtr->item = newItem;
		nodePtr->next = GetNodePtr(index);
		prevPtr = GetNodePtr(index - 1);
		prevPtr->next = nodePtr;
		m_numItems++;
		return;
	}
	
	// else throw exception due to invalid index
	else
	{
	    //throw CListEx(INVALID_INDEX);
		cout << "Error: InsertItem" << endl;
		return;
	}
	
} // end of "InsertItem"



// ==== RemoveItem ============================================================
// 
// This function removes an item at target index location.
//
// Input:
//		index	--	an int storing the index to the node the caller wants to
//					remove.
//
// Output:
//
// ============================================================================

template<typename Type>
void        CSimpleList<Type>::RemoveItem(int  index)
{
    auto    LNode<Type>		*nodePtr = NULL;
    auto    LNode<Type>		*tempPtr = NULL;
    
    // if the list is empty, throw an exception
    if (true == IsListEmpty())
    {
        //throw CListEx(LIST_EMPTY);
		cout << "Error: RemoveItem: " << endl;
		return;
    }
    
    // get pointer for zero-based node to be removed
    nodePtr = GetNodePtr(index);
    
    // if invalid pointer is returned, throw error
    if (NULL == nodePtr)
    {
        //throw CListEx(INVALID_INDEX);
		cout << "Error: RemoveItem: " << endl;
		return;
    }
    
    // else remove that item
    else
    {
        tempPtr = GetNodePtr(index - 1);
        
        // handle removal from head of the list
        if (NULL == tempPtr)
        {
            m_headPtr = nodePtr->next;
            delete nodePtr;
            m_numItems--;
        }
        
        // else remove item from the middle/end of the list
        else
        {
            tempPtr->next = nodePtr->next;
            delete nodePtr;
            m_numItems--;
        }
    }
	
    return;
	
} // end of "RemoveItem"



// ==== CopyList ==============================================================


template<typename Type>
int             CSimpleList<Type>::CopyList(const CSimpleList<Type>  &otherList)
{
	auto	int		index;
	auto	Type	otherItem;
	
	DestroyList();
	CreateList();
	m_numItems = otherList.m_numItems;
	
	for (index = 0; index < m_numItems; index++)
	{
	    otherList.GetListItem(index, otherItem);
		InsertItem(index, otherItem); 
	}
	
	return index;
	
} // end of "CopyList"



// ==== GetNodePtr ============================================================
// 
// This function is used to gain indexed access into the linked list.  If an
// invalid index is provided (beyond the allocated amount of nodes), a NULL
// pointer is returned.
//
// Input:
//		index	--	an int storing the index to the node the caller wants a
//					pointer to.
//
// Output:
//		If a valid index is provided, a reference to the LNode at the caller's
//		index is returned, otherwise a NULL pointer is returned.
//
// ============================================================================

template<typename Type>
LNode<Type>*          CSimpleList<Type>::GetNodePtr(int  index) const
{
    auto    LNode<Type>		*leadPtr = m_headPtr;
    auto    int				counter;
    
    // if invalid (negative index) is provided, return null
    if (index < 0)
    {
        return NULL;
    }
    
    // index through the array until either target index or end of list is
    // reached
    for (counter = 0; ((counter < index) && (leadPtr != NULL)); counter++)
    {
        leadPtr = leadPtr->next;
    }
    
    // leadPtr now contains either a pointer to the target LNode or NULL, so
    // return leadPtr
    return leadPtr;
	
} // end of "GetNodePtr;



// ==== operator= =============================================================


template<typename Type>
CSimpleList<Type>&    CSimpleList<Type>::operator=(const CSimpleList<Type>  &rhs)
{
	if (this != &rhs)
	{
		CopyList(rhs);
	}
	
	return *this;	
} // end of "operator=" 


#endif  // CSIMPLELIST_H  
That should now compile and link (at least it did on Microsoft visual Studio)
Yep linked an ran, except the include in main has to be after using namespace std; - now neither my instert or remove functions want to work so i'll see what's up with that. thanks for your help!
Works! Thank you very much. The time is appreciated. I would still like to know why it didn't work the way our instructor taught us - i've done it before with a smaller class and it worked fine. Strange. Hmm.. now I have to get to templatizing my CStack class! Should go much smoother this time.
I don't think your instructor would have have given you a wrong way to do it.
maybe in all the rush we just got a bit confused about his method.

Topic archived. No new replies allowed.