What I am trying to do:
I have a problem -- but I suppose you might have guessed that.
I am trying to write a tree of arbitrary data. The idea behind it is:
for the programmer using it -- most likely me -- will be able to store any data type in the tree and access it through a key. The tree will dynamically sort all the data according to the value of the key. This tree consists of two classes the main class called "cNode" and the class called "cTree". Why did I separate them into two classes I don't know but I am sure I had a good reason for that. I declared each class in it's own header and defined the methods if the corresponding "*.cpp" file the problem is during linking.
What is happening:
When linking I get the following errors:
LinkLists error LNK2019: unresolved external symbol "public: __thiscall Tree::cTree<unsigned int>::cTree<unsigned int>(void)" (??0?$cTree@I@Tree@@QAE@XZ) referenced in function _main
LinkLists error LNK2019: unresolved external symbol "public: void __thiscall Tree::cTree<unsigned int>::Add(int,unsigned int)" (?Add@?$cTree@I@Tree@@QAEXHI@Z) referenced in function _main
I know the have been defined because I wrote them in the *.cpp
I have done this with other programs. I am curious as to what is happening here. I figured I missed something.
Here are the usual specs...
compiler: Microsoft Visual C++.Net 2003
The Source Code:
Code:
/***********Nodes.h*****************************/
#ifndef _NODES_H
#define _NODES_H
#include <iostream>
using namespace std;
namespace Nodes
{
template<typename object>
class cNode
{
private:
///////Private members///////////
cNode *m_pLeft;
cNode *m_pRight;
int m_iCount;
int m_iKey;
object m_Item;
////////Private methods//////////////////////////////////////
void KillNodes(cNode *pNode); // Destroys the whole tree
cNode *FindEmptyChildNode(int iKey, cNode *pNode, bool Add = false); //Finds the last empty child node
void InitializeNode(int iKey, object Item, cNode &pNode); //Initializes the new node
public:
//////////General Methods////////////////////////////////////
void AddItem(int iKey, object Item);
//////////Constructors/Deconstructors////////////////////////
cNode<object>();
~cNode(){KillNodes(this);}
///////Get/Set Methods//////////////////////////////////////
cNode *GetLeft(){return m_pLeft;}
cNode *GetRight(){return m_pRight;}
int GetCount(){return m_iCount;}
int GetKey(){return m_iKey;}
object GetItem(){return m_Item;}
void SetKey(int iKey){m_iKey = iKey;}
void SetItem(object Item){m_Item = Item;}
};
}
#endif
Code:
/*******************Nodes.cpp**************************/
#include "Nodes.h"
using namespace Nodes;
/**********************Class cNode***************************************/
//////////////////////////////////////////////////////////////////////////
//Name: cNode
//Type: Constructor
//Description: Initializes the node.
//////////////////////////////////////////////////////////////////////////
template<typename object>
cNode<object>::cNode()
{
m_pLeft = NULL;
m_pRight = NULL;
m_iCount+=1;
}
//////////////////////////////////////////////////////////////////////////
//Name: KillNodes
//Type: Private Method
//Description: Destroys all nodes starting at the bottom of the tree
//////////////////////////////////////////////////////////////////////////
template<typename object>
void cNode<object>::KillNodes(cNode<object> *pNode)
{
if(pNode != NULL)
{
KillSubNodes(pNode->GetLeft());
KillSubNodes(pNode->GetRight());
delete pNode;
}
}
//////////////////////////////////////////////////////////////////////////
//Name: FindEmptyChildNode
//Type: Private Method
//Description: Finds the last empty node it will decide which path to take
// depending on the key passed to it.
//////////////////////////////////////////////////////////////////////////
template<typename object>
cNode<object> *cNode<object>::FindEmptyChildNode(int iKey, cNode<object> *pNode, bool Add)
{
if(Add == true)
pNode->m_iCount +=1;
if(pNode == NULL)
{
return (pNode = new cNode<object>());
}
else if(pNode->GetKey() > iKey)
{
return FindEmptyChildNode(iKey, pNode->GetLeft());
}
else if(pNode->GetKey() < iKey)
{
return FindEmptyChildNode(iKey, pNode->GetRight());
}
}
//////////////////////////////////////////////////////////////////////////
//Name: InitializeNode
//Type: Private Method
//Description: Sets all the variables inside the given node.
//////////////////////////////////////////////////////////////////////////
template<typename object>
void cNode<object>::InitializeNode(int iKey, object Item, cNode<object> &pNode)
{
pNode.SetKey(iKey);
pNode.SetItem(Item);
}
//////////////////////////////////////////////////////////////////////////
//Name: AddItem
//Type: Public Method
//Description: Creates a new node and sets it's values the values pass in.
//////////////////////////////////////////////////////////////////////////
template<typename object>
void cNode<object>::AddItem(int iKey, object Item)
{
if(this == NULL)
{
this->SetKey(iKey);
this->SetItem(Item);
}
else if(this->GetKey() > iKey)
{
InitializeNode(iKey, Item,FindEmptyChildNode(iKey, this->GetLeft(), true));
}
else if(this->GetKey() < iKey)
{
InitializeNode(iKey, Item,FindEmptyChildNode(iKey, this->GetRight(), true));
}
}
Code:
#ifndef _TREE_H
#define _TREE_H
/********************Tree.h************************************************/
#include <iostream>
#include "Nodes.h"
using namespace Nodes;
using namespace std;
namespace Tree
{
template<typename object>
class cTree
{
private:
/////// Private Members ///////
cNode<object> *m_pNode;
cNode<object> *SearchChild(int iKey, cNode<object> *pNode);
public:
cTree();
~cTree();
void Add(int iKey, object Item);
cNode<object>* Search(int iKey, object Item);
cNode<object>* Search(int iKey);
};
}
#endif
Code:
/**********************Tree.cpp****************************************/
#include "Tree.h"
using namespace Tree;
/***************Class cTree********************************************/
//////////////////////////////////////////////////////////////////////////
//Name: cTree
//Type: Contructor
//Description: Initializes a new cTree object.
//////////////////////////////////////////////////////////////////////////
template<typename object>
cTree<object>::cTree()
{
m_pNode = new cNode<object>();
}
template<typename object>
cTree<object>::~cTree()
{
delete m_pNode;
}
//////////////////////////////////////////////////////////////////////////
//Name: Search
//Type: Public Method
//Description: Finds the Item and returns the node that contains it.
//////////////////////////////////////////////////////////////////////////
template<typename object>
cNode<object> *cTree<object>::Search(int iKey, object Item)
{
cNode<object> * pTemp;
if(m_pNode == NULL)
return m_pNode;
else if(m_pNode->GetItem() == Item)
return m_pNode;
else if(m_pNode->GetKey() > iKey)
{
pTemp = SearchChild(iKey, m_pNode->GetLeft());
if(pTemp == NULL)
return pTemp;
else if(pTemp->GetItem() == Item)
return pTemp;
else
return (pTemp = NULL);
}
else if(m_pNode->GetKey() < iKey)
{
pTemp = SearchChild(iKey, m_pNode->GetRight());
if(pTemp == NULL)
return pTemp;
else if(pTemp->GetItem() == Item)
return pTemp;
else
return (pTemp = NULL);
}
}
//////////////////////////////////////////////////////////////////////////
//Name: Search
//Type: Public Method
//Description: Finds the Key and returns the node that contains it.
//////////////////////////////////////////////////////////////////////////
template<typename object>
cNode<object> *cTree<object>::Search(int iKey)
{
if(m_pNode == NULL)
return m_pNode;
else if(m_pNode->GetKey() == iKey)
return m_pNode;
else if(m_pNode->GetKey() > iKey)
return SearchChild(iKey, m_pNode->GetLeft());
else if(m_pNode->GetKey() < iKey)
return SearchChild(iKey, m_pNode->GetRight());
}
//////////////////////////////////////////////////////////////////////////
//Name: SearchChild
//Type: Private Method
//Description: Finds the Key and returns the child node that contains it.
//////////////////////////////////////////////////////////////////////////
template<typename object>
cNode<object> *cTree<object>::SearchChild(int iKey, cNode<object> *pNode)
{
if(pNode == NULL)
return pNode;
else if(pNode->GetKey() == iKey)
return pNode;
else if(pNode->GetKey() > iKey)
return SearchChild(iKey, pNode->GetLeft());
else if(pNode->GetKey() < iKey)
return SearchChild(iKey, pNode->GetRight());
}
//////////////////////////////////////////////////////////////////////////
//Name: Add
//Type: Public Method
//Description: Adds a new node to the tree.
//////////////////////////////////////////////////////////////////////////
template<typename object>
void cTree<object>::Add(int iKey, object Item)
{
m_pNode->AddItem(iKey, Item);
}
Code:
/****************main.cpp****************************/
#include <iostream>
#include "Tree.h"
using namespace std;
using namespace Tree;
int main(int argv, char* argc[])
{
cTree<unsigned int> *tree = new cTree<unsigned int>();
tree->Add(25,0x4455);
tree->Add(20,0xFFCC);
tree->Add(23,0xD05C);
return 0;
}
Sorry I just got tired of doing syntax highlighting
Any help you can offer will be appreciated ... thanks in advance