Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Categories

Welcome to the new platform of Programmer's Heaven! We apologize for the inconvenience caused, if you visited us from a broken link of the previous version. The main reason to move to a new platform is to provide more effective and collaborative experience to you all. Please feel free to experience the new platform and use its exciting features. Contact us for any issue that you need to get clarified. We are more than happy to help you.

Attempt at Linked List Template Class

mikfigmikfig Posts: 7Member
I just coded out a linked list template class, its my first attempt at template coding. It compiles fine; however, I get these 3 linker errors:
[code]
error LNK2019: unresolved external symbol "public: __thiscall LinkedList::~LinkedList(void)" (??1?$LinkedList@H$0A@@@QAE@XZ) referenced in function _main main.obj
error LNK2019: unresolved external symbol "public: int & __thiscall ListIterator::operator()(void)" (??R?$ListIterator@H$0A@@@QAEAAHXZ) referenced in function _main main.obj
error LNK2019: unresolved external symbol "public: class ListIterator & __thiscall LinkedList::insertAfter(class ListIterator,int const &)" (?insertAfter@?$LinkedList@H$0A@@@QAEAAV?$ListIterator@H$0A@@@V2@ABH@Z) referenced in function _main main.obj
[/code]

Here is the code:
main.cpp
[code]
//main.cpp
#include "LinkedList.h"

int main()
{
LinkedList list;
ListIterator listBegin = list.begin();

list.insertAfter(listBegin, 10);
listBegin() = 5;
return 0;
}
[/code]

LinkedList.h
[code]
//LinkedList.h
#include "ListIterator.h"
#include "ListNode.h"

#ifndef __LINKED_LIST__
#define __LINKED_LIST__

template
class LinkedList
{
public:
LinkedList() : m_head(0), m_tail(0), m_iNodes(0)
{ }
LinkedList(const LinkedList &ll) : m_head(ll.m_head), m_tail(ll.m_tail), m_iNodes(ll.m_iNodes)
{ }
~LinkedList();

ListIterator begin() { return ListIterator(m_head); }
ListIterator end() { return ListIterator(m_tail); }

ListIterator& insertBefore(ListIterator p_iter, const tDataType& data);
ListIterator& insertAfter(ListIterator p_iter, const tDataType& data);
void remove(ListIterator p_iter);

protected:
ListNode* m_head;
ListNode* m_tail;
int m_iNodes;
};

#endif
[/code]

LinkedList.cpp
[code]
//LinkedList.cpp
#include "LinkedList.h"

template
LinkedList::~LinkedList()
{
if(m_head != 0)
{
ListNode* pPrev = m_head;
ListNode* pNext;

while(pPrev != 0)
{
pNext = pNext->m_next;
delete pPrev;
pPrev = pNext;
}
}
}

template
ListIterator& LinkedList::insertBefore(ListIterator p_iter, const tDataType& data)
{
if(m_iNodes != 0)
{
if(&p_iter == m_head || !(&p_iter))
{
m_head->prev = new ListNode(data, &p_iter, 0);
m_iNodes++;
return ListIterator(m_head->m_prev);
}
else
{
(&(p_iter - 1)).next = new ListNode(data, &p_iter, &(p_iter - 1));
(&p_iter).prev = (&(p_iter - 1)).next;
return ListIterator((&p_iter).prev);
}
}
else
{
m_tail = m_head = new ListNode(data, &p_iter, 0);
m_iNodes = 1;
return ListIterator(m_head);
}
}

template
ListIterator& LinkedList::insertAfter(ListIterator p_iter, const tDataType& data)
{
if(m_iNodes != 0)
{
if(&p_iter == m_tail || !(&p_iter))
{
m_tail->next = new ListNode(data, &p_iter, 0);
m_iNodes++;
return ListIterator(m_tail->next);
}
else
{
(&(p_iter - 1)).next = new ListNode(data, &p_iter, &(p_iter - 1));
(&p_iter).prev = (&(p_iter - 1)).next;
return ListIterator((&p_iter).prev);
}
}
else
{
m_tail = m_head = new ListNode(data, &p_iter, 0);
m_iNodes = 1;
return ListIterator(m_head);
}
}

template
void LinkedList::remove(ListIterator p_iter)
{
if(m_iNodes != 0)
{
if(m_iNodes == 1)
{
delete m_head;
m_tail = m_head = 0;
m_iNodes = 0;
}
else
{
if(p_iter == m_head)
{
ListNode* pTemp = m_head->m_next;
delete m_head;
m_head = pTemp;
m_head->m_prev = 0;
m_iNodes--;
}
else if(p_iter == m_tail)
{
ListNode* pTemp = m_tail->m_prev;
delete m_tail;
m_tail = pTemp;
m_tail->m_next = 0;
m_iNodes--;
}
else
{
ListNode* prev = (&p_iter)->m_prev;
ListNode* next = (&p_iter)->m_next;
delete (&p_iter);
prev->m_next = next;
next->m_prev = prev;
m_iNodes--;
}
}
}
}
[/code]

ListNode.h
[code]
//ListNode.h
#ifndef __LIST_NODE__
#define __LIST_NODE__

template
class ListNode
{
public:
ListNode() : m_data(tZeroVal), m_next(0), m_prev(0)
{ }
ListNode(const ListNode &ln) : m_data(ln.m_data), m_next(ln.m_next), m_prev(ln.m_prev)
{ }
ListNode(tDataType& p_data) : m_data(p_data), m_next(0), m_prev(0)
{ }
ListNode(ListNode* p_prev, ListNode* p_next) : m_data(tZeroVal), m_next(p_next), m_prev(p_prev)
{ }
ListNode(tDataType& p_data, ListNode* p_next, ListNode* p_prev) : m_data(p_data), m_next(p_next), m_prev(p_prev)
{ }

tDataType m_data;
ListNode* m_next;
ListNode* m_prev;
};

#endif
[/code]

ListIterator.h
[code]
//ListIterator.h
#include "ListNode.h"

#ifndef __LIST_ITERATOR__
#define __LIST_ITERATOR__

template
class ListIterator
{
public:
ListIterator() : m_node(0)
{ }
ListIterator(const ListIterator& iter) : m_node(iter.m_node)
{ }
ListIterator(ListNode* p_node) : m_node(p_node)
{ }

ListNode* operator&() { return m_node; }
ListIterator& operator++();
ListIterator& operator++(int dummy);
ListIterator& operator--();
ListIterator& operator--(int dummy);
ListIterator& operator+(int p_amount);
ListIterator& operator-(int p_amount);
tDataType& operator[](int p_amount);
tDataType& operator()();
private:
ListNode* m_node;
};

#endif
[/code]

ListIterator.cpp
[code]
//ListIterator.cpp
#include "ListIterator.h"

template
ListIterator& ListIterator::operator++()
{
if(m_node != 0 && m_node->m_next != 0)
{
m_node = m_node->m_next;
}
return *this;
}

template
ListIterator& ListIterator::operator++(int dummy)
{
if(m_node != 0 && m_node->m_next != 0)
{
ListNode* temp = m_node;
m_node = m_node->m_next;
return ListIterator(temp);
}
else
{
return *this;
}
}

template
ListIterator& ListIterator::operator--()
{
if(m_node != 0 && m_node->m_prev != 0)
{
m_node = m_node->m_prev;
}
return *this;
}

template
ListIterator& ListIterator::operator--(int dummy)
{
if(m_node != 0 && m_node->m_prev != 0)
{
ListNode* temp = m_node;
m_node = m_node->m_prev;
return ListIterator(temp);
}
else
{
return *this;
}
}

template
ListIterator& ListIterator::operator+(int p_amount)
{
if(m_node != 0 && m_node->m_next != 0)
{
ListNode* newNode = m_node;

for(int i = 0; (i < p_amount) && (newNode->next != 0); i++)
newNode = newNode->m_next;
return ListIterator(newNode);
}
return *this;
}

template
ListIterator& ListIterator::operator-(int p_amount)
{
if(m_node != 0 && m_node->m_prev != 0)
{
ListNode* newNode = m_node;

for(int i = 0; (i < p_amount) && (newNode->prev != 0); i++)
newNode = newNode->m_prev;
return ListIterator(newNode);
}
return *this;
}

template
tDataType& ListIterator::operator[](int p_amount)
{
if(m_node != 0)
{
ListNode* newNode = m_node;

for(int i = 0; (i < p_amount) && (newNode->next != 0); i++)
newNode = newNode->m_next;
return newNode->m_data;
}
return tZeroVal;
}

template
tDataType& ListIterator::operator()()
{
if(m_node != 0)
{
return m_node->m_data;
}
return tZeroVal;
}
[/code]

Any tips will be appreciated as well.

Thanks,
Mikfig

Comments

  • mikfigmikfig Posts: 7Member
    : I just coded out a linked list template class, its my first attempt
    : at template coding. It compiles fine; however, I get these 3 linker
    : errors:
    : [code]:
    : error LNK2019: unresolved external symbol "public: __thiscall LinkedList::~LinkedList(void)" (??1?$LinkedList@H$0A@@@QAE@XZ) referenced in function _main main.obj
    : error LNK2019: unresolved external symbol "public: int & __thiscall ListIterator::operator()(void)" (??R?$ListIterator@H$0A@@@QAEAAHXZ) referenced in function _main main.obj
    : error LNK2019: unresolved external symbol "public: class ListIterator & __thiscall LinkedList::insertAfter(class ListIterator,int const &)" (?insertAfter@?$LinkedList@H$0A@@@QAEAAV?$ListIterator@H$0A@@@V2@ABH@Z) referenced in function _main main.obj
    : [/code]:
    :
    : Here is the code:
    : main.cpp
    : [code]:
    : //main.cpp
    : #include "LinkedList.h"
    :
    : int main()
    : {
    : LinkedList list;
    : ListIterator listBegin = list.begin();
    :
    : list.insertAfter(listBegin, 10);
    : listBegin() = 5;
    : return 0;
    : }
    : [/code]:
    :
    : LinkedList.h
    : [code]:
    : //LinkedList.h
    : #include "ListIterator.h"
    : #include "ListNode.h"
    :
    : #ifndef __LINKED_LIST__
    : #define __LINKED_LIST__
    :
    : template
    : class LinkedList
    : {
    : public:
    : LinkedList() : m_head(0), m_tail(0), m_iNodes(0)
    : { }
    : LinkedList(const LinkedList &ll) : m_head(ll.m_head), m_tail(ll.m_tail), m_iNodes(ll.m_iNodes)
    : { }
    : ~LinkedList();
    :
    : ListIterator begin() { return ListIterator(m_head); }
    : ListIterator end() { return ListIterator(m_tail); }
    :
    : ListIterator& insertBefore(ListIterator p_iter, const tDataType& data);
    : ListIterator& insertAfter(ListIterator p_iter, const tDataType& data);
    : void remove(ListIterator p_iter);
    :
    : protected:
    : ListNode* m_head;
    : ListNode* m_tail;
    : int m_iNodes;
    : };
    :
    : #endif
    : [/code]:
    :
    : LinkedList.cpp
    : [code]:
    : //LinkedList.cpp
    : #include "LinkedList.h"
    :
    : template
    : LinkedList::~LinkedList()
    : {
    : if(m_head != 0)
    : {
    : ListNode* pPrev = m_head;
    : ListNode* pNext;
    :
    : while(pPrev != 0)
    : {
    : pNext = pNext->m_next;
    : delete pPrev;
    : pPrev = pNext;
    : }
    : }
    : }
    :
    : template
    : ListIterator& LinkedList::insertBefore(ListIterator p_iter, const tDataType& data)
    : {
    : if(m_iNodes != 0)
    : {
    : if(&p_iter == m_head || !(&p_iter))
    : {
    : m_head->prev = new ListNode(data, &p_iter, 0);
    : m_iNodes++;
    : return ListIterator(m_head->m_prev);
    : }
    : else
    : {
    : (&(p_iter - 1)).next = new ListNode(data, &p_iter, &(p_iter - 1));
    : (&p_iter).prev = (&(p_iter - 1)).next;
    : return ListIterator((&p_iter).prev);
    : }
    : }
    : else
    : {
    : m_tail = m_head = new ListNode(data, &p_iter, 0);
    : m_iNodes = 1;
    : return ListIterator(m_head);
    : }
    : }
    :
    : template
    : ListIterator& LinkedList::insertAfter(ListIterator p_iter, const tDataType& data)
    : {
    : if(m_iNodes != 0)
    : {
    : if(&p_iter == m_tail || !(&p_iter))
    : {
    : m_tail->next = new ListNode(data, &p_iter, 0);
    : m_iNodes++;
    : return ListIterator(m_tail->next);
    : }
    : else
    : {
    : (&(p_iter - 1)).next = new ListNode(data, &p_iter, &(p_iter - 1));
    : (&p_iter).prev = (&(p_iter - 1)).next;
    : return ListIterator((&p_iter).prev);
    : }
    : }
    : else
    : {
    : m_tail = m_head = new ListNode(data, &p_iter, 0);
    : m_iNodes = 1;
    : return ListIterator(m_head);
    : }
    : }
    :
    : template
    : void LinkedList::remove(ListIterator p_iter)
    : {
    : if(m_iNodes != 0)
    : {
    : if(m_iNodes == 1)
    : {
    : delete m_head;
    : m_tail = m_head = 0;
    : m_iNodes = 0;
    : }
    : else
    : {
    : if(p_iter == m_head)
    : {
    : ListNode* pTemp = m_head->m_next;
    : delete m_head;
    : m_head = pTemp;
    : m_head->m_prev = 0;
    : m_iNodes--;
    : }
    : else if(p_iter == m_tail)
    : {
    : ListNode* pTemp = m_tail->m_prev;
    : delete m_tail;
    : m_tail = pTemp;
    : m_tail->m_next = 0;
    : m_iNodes--;
    : }
    : else
    : {
    : ListNode* prev = (&p_iter)->m_prev;
    : ListNode* next = (&p_iter)->m_next;
    : delete (&p_iter);
    : prev->m_next = next;
    : next->m_prev = prev;
    : m_iNodes--;
    : }
    : }
    : }
    : }
    : [/code]:
    :
    : ListNode.h
    : [code]:
    : //ListNode.h
    : #ifndef __LIST_NODE__
    : #define __LIST_NODE__
    :
    : template
    : class ListNode
    : {
    : public:
    : ListNode() : m_data(tZeroVal), m_next(0), m_prev(0)
    : { }
    : ListNode(const ListNode &ln) : m_data(ln.m_data), m_next(ln.m_next), m_prev(ln.m_prev)
    : { }
    : ListNode(tDataType& p_data) : m_data(p_data), m_next(0), m_prev(0)
    : { }
    : ListNode(ListNode* p_prev, ListNode* p_next) : m_data(tZeroVal), m_next(p_next), m_prev(p_prev)
    : { }
    : ListNode(tDataType& p_data, ListNode* p_next, ListNode* p_prev) : m_data(p_data), m_next(p_next), m_prev(p_prev)
    : { }
    :
    : tDataType m_data;
    : ListNode* m_next;
    : ListNode* m_prev;
    : };
    :
    : #endif
    : [/code]:
    :
    : ListIterator.h
    : [code]:
    : //ListIterator.h
    : #include "ListNode.h"
    :
    : #ifndef __LIST_ITERATOR__
    : #define __LIST_ITERATOR__
    :
    : template
    : class ListIterator
    : {
    : public:
    : ListIterator() : m_node(0)
    : { }
    : ListIterator(const ListIterator& iter) : m_node(iter.m_node)
    : { }
    : ListIterator(ListNode* p_node) : m_node(p_node)
    : { }
    :
    : ListNode* operator&() { return m_node; }
    : ListIterator& operator++();
    : ListIterator& operator++(int dummy);
    : ListIterator& operator--();
    : ListIterator& operator--(int dummy);
    : ListIterator& operator+(int p_amount);
    : ListIterator& operator-(int p_amount);
    : tDataType& operator[](int p_amount);
    : tDataType& operator()();
    : private:
    : ListNode* m_node;
    : };
    :
    : #endif
    : [/code]:
    :
    : ListIterator.cpp
    : [code]:
    : //ListIterator.cpp
    : #include "ListIterator.h"
    :
    : template
    : ListIterator& ListIterator::operator++()
    : {
    : if(m_node != 0 && m_node->m_next != 0)
    : {
    : m_node = m_node->m_next;
    : }
    : return *this;
    : }
    :
    : template
    : ListIterator& ListIterator::operator++(int dummy)
    : {
    : if(m_node != 0 && m_node->m_next != 0)
    : {
    : ListNode* temp = m_node;
    : m_node = m_node->m_next;
    : return ListIterator(temp);
    : }
    : else
    : {
    : return *this;
    : }
    : }
    :
    : template
    : ListIterator& ListIterator::operator--()
    : {
    : if(m_node != 0 && m_node->m_prev != 0)
    : {
    : m_node = m_node->m_prev;
    : }
    : return *this;
    : }
    :
    : template
    : ListIterator& ListIterator::operator--(int dummy)
    : {
    : if(m_node != 0 && m_node->m_prev != 0)
    : {
    : ListNode* temp = m_node;
    : m_node = m_node->m_prev;
    : return ListIterator(temp);
    : }
    : else
    : {
    : return *this;
    : }
    : }
    :
    : template
    : ListIterator& ListIterator::operator+(int p_amount)
    : {
    : if(m_node != 0 && m_node->m_next != 0)
    : {
    : ListNode* newNode = m_node;
    :
    : for(int i = 0; (i < p_amount) && (newNode->next != 0); i++)
    : newNode = newNode->m_next;
    : return ListIterator(newNode);
    : }
    : return *this;
    : }
    :
    : template
    : ListIterator& ListIterator::operator-(int p_amount)
    : {
    : if(m_node != 0 && m_node->m_prev != 0)
    : {
    : ListNode* newNode = m_node;
    :
    : for(int i = 0; (i < p_amount) && (newNode->prev != 0); i++)
    : newNode = newNode->m_prev;
    : return ListIterator(newNode);
    : }
    : return *this;
    : }
    :
    : template
    : tDataType& ListIterator::operator[](int p_amount)
    : {
    : if(m_node != 0)
    : {
    : ListNode* newNode = m_node;
    :
    : for(int i = 0; (i < p_amount) && (newNode->next != 0); i++)
    : newNode = newNode->m_next;
    : return newNode->m_data;
    : }
    : return tZeroVal;
    : }
    :
    : template
    : tDataType& ListIterator::operator()()
    : {
    : if(m_node != 0)
    : {
    : return m_node->m_data;
    : }
    : return tZeroVal;
    : }
    : [/code]:
    :
    : Any tips will be appreciated as well.
    :
    : Thanks,
    : Mikfig
    :
    :
    Never mind, fixed it and works perfectly.
  • dotman6dotman6 Posts: 4Member
    could i ask how you fixed it cos i am attempting a linked list class template to and i'm having similar linker errors
  • mikfigmikfig Posts: 7Member
    Yea, of course. The member functions of the template class have to be defined in the same file. I can't remember exactly, but that is I think the solution was.

    I solved this over at gamedev.net if you want to see the full topic.
    http://www.gamedev.net/community/forums/topic.asp?topic_id=518965
Sign In or Register to comment.