i decided to create a list (for practice reasons so get off my back about reinvening the wheel thanks..)
I got this LNK2019 ERROR and i belive its code specific becus i cant seem to find a way to fix it ( yes i serched here )
I have found that the problom is coused beacous the complier does not recognize the definitions of the methods, but i cant seem to find out whay. I am using MVS 2010 so the link args are done automatically. here is my code.
List H:
#ifndef _DLIST
#define _DLIST
#include "Node.h"
template<class DataO>
class Dlist
{
private:
/* Data Members */
Node<DataO>* _ndHead;
Node<DataO>* _ndTail;
unsigned int _nLength;
/* Methods */
void Delete();
public:
/* Ctors && Dtors */
Dlist();
~Dlist();
/* Getters && Setters */
int Length();
/* Methods */
void Add(DataO doData);
void Clear();
void RemoveAt(unsigned int nIndex);
void Remove();
};
#endif
List Cpp:
// Dlist.cpp
#include "Dlist.h"
/* ------------------ Dlist Section ------------------ */
/* --- Constracturs && Destractur --- */
template<class DataO>
Dlist<DataO> :: Dlist()
{
// Init data
this->_ndHead = NULL;
this->_ndTail = NULL;
this->_nLength = 0;
}
template<class DataO>
Dlist<DataO> :: ~Dlist()
{
// Check if we have nodes to delete
if (this->_nLength > 0);
{
this->Clear();
}
}
/* --- Methods -- */
template<class DataO>
int Dlist<DataO> :: Length()
{
// Return the length
return (this->Length);
}
template<class DataO>
void Dlist<DataO> :: Add(DataO doData)
{
// Check if head is null
if (this->_ndHead == NULL)
{
// Create head
this->_ndHead = new Node<DataO>(doData, NULL, NULL);
}
// Check if tail is null
else if (this->_ndTail == NULL)
{
// Create tail
this->_ndTail = new Node<DataO>(doData, NULL, this->_ndHead);
// Set head's next
this->_ndHead->SetNext(this->_ndTail);
}
// Create a new Node and replace the tail.
else
{
// Create a new node.
this->_ndTail->_ndNext = new Node<DataO>(doData, NULL, this->_ndTail);
// Make the new node the tail
this->_ndTail = this->_ndTail->_ndNext;
}
}
Node H:
template<class DataO>
class Node
{
private:
/* Data Members */
DataO _doData;
Node<DataO>* _ndPrev;
Node<DataO>* _ndNext;
/* Methods */
void Delete();
public:
/* Ctors && Dtors */
Node<DataO>(DataO doData);
Node<DataO>(DataO doData, const Node& ndNext, const Node& ndPrev);
~Node();
/* Getters && Setters */
DataO& GetData();
void SetData(DataO doData);
const Node& GetNext();
void SetNext(const Node* ndNextNode);
const Node& GetPrev();
void SetPrev(const Node* ndPrevNode);
};
Node Cpp:
// Node.cpp
#include "Node.h"
/* ------------------ Node Section ------------------ */
/* --- Constracturs --- */
template<class DataO>
Node<DataO> :: Node(DataO doData)
{
// Init data
this->SetData(doData);
this->SetNext(NULL);
this->SetPrev(NULL);
}
template<class DataO>
Node<DataO> :: Node(DataO doData, const Node& ndNext, const Node& ndPrev)
{
// Init data
this->SetData(doData);
this->SetNext(ndNext);
this->SetPrev(ndPrev);
}
/*
- Node destructor -
- Maneges the change of nodes.
- Changes the Previous node next node,
- to the current node next node.
*/
template<class DataO>
Node<DataO> :: ~Node()
{
// Check that prev is not null
if (this->GetPrev != NULL)
{
// Set prevs Next to current next
this->GetPrev().SetNext(this->GetNext());
}
}
/*
- GetData -
- Returns the data stored in the Node.
*/
template<class DataO>
DataO& Node<DataO> :: GetData()
{
// Return the data
return (this->_doData&);
}
/*
- SetData -
- Sets the data stored in the Node.
*/
template<class DataO>
void Node<DataO> :: SetData(DataO doData)
{
// Sets data
this->_doData = doData;
}
/*
- GetNext -
- Returns the next node in the list.
*/
template<class DataO>
const Node<DataO>& Node<DataO> :: GetNext()
{
// Returns the next node in the list.
return (this->_ndNext&);
}
/*
- SetNext -
- Set the next node in the list.
*/
template<class DataO>
void Node<DataO> :: SetNext(const Node* ndNextNode)
{
// Set next node as given node
this->_ndNext = ndNextNode;
}
/*
- GetPrev -
- Returns the previous node in the list.
*/
template<class DataO>
const Node<DataO>& Node<DataO> :: GetPrev()
{
// Returns the next node in the list.
return (this->_ndPrev&);
}
/*
- SetPrev -
- Set the previous node in the list.
*/
template<class DataO>
void Node<DataO> :: SetPrev(const Node* ndPrevNode)
{
// Set next node as given node
this->GetPrev = ndPrevNode;
}
This happens because MSVC compiler does not support extern template. I see your idea, this would be correct approach, but it does not work with most of the compilers. This is because the compiler needs to have access to the entire template definition (not just the signature) in order to generate code for each instantiation of the template. You have 2 options to make it work:
Define all the methods in the header file (like most of the Boost libraries do)
Explicitly instantiate your template class for predefined types (this way your class will not be generic)
See detailed explanation here