简体   繁体   English

模板化的二进制搜索树C ++,未解决的外部错误

[英]Templated binary search tree c++, unresolved external error

I am working on a template for a binary search tree and I am getting the error below. 我正在为二叉搜索树设计模板,但出现以下错误。 I know there are similar post but I can't figure this thing out. 我知道有类似的帖子,但我无法弄清楚。 Templates are definitely a weak subject for me so I think I am missing some fundamental semantic thing but I can put my finger on it. 模板对我来说绝对是一个薄弱的话题,因此我认为我缺少一些基本的语义方面的内容,但是我可以全力以赴。 Below is the error than after that are the files of the program. 以下是该文件之后的错误。 If anyone could point me in the right direction I would really appreciate it. 如果有人能指出正确的方向,我将不胜感激。

Error 1 error LNK2019: unresolved external symbol "private: bool __thiscall Tree::insertHelper(class TreeNode * &,int)" (?insertHelper@?$Tree@H@@AAE_NAAPAV?$TreeNode@H@@H@Z) referenced in function "public: bool __thiscall Tree::insert(int)" (?insert@?$Tree@H@@QAE_NH@Z) C:\\Users\\wm\\documents\\visual studio 2012\\Projects\\binaryTree\\binaryTree\\main.obj 错误1错误LNK2019:未解析的外部符号“专用:bool __thiscall Tree :: insertHelper(TreeTree *&,int)类”(?insertHelper @?$ Tree @ H @@ AAE_NAAPAV?$ TreeNode @ H @@ H @ Z)在函数“ public:bool __thiscall Tree :: insert(int)”中(?insert @?$ Tree @ H @@ QAE_NH @ Z)C:\\ Users \\ wm \\ documents \\ visual studio 2012 \\ Projects \\ binaryTree \\ binaryTree \\ main .obj

-basic main for testing -测试的基本主

#include "BinarySearchTree.h"
#include "TreeNode.h"
#include <iostream>

using namespace std;

int main()
{
    Tree<int> test;
    test.insert(55);

    return 0;
}

-tree template 树模板

#include <iostream>
#include "TreeNode.h"

using namespace std;

template< class ItemType >
class Tree {
public:

   Tree(); 
   ~Tree();     
   bool isEmpty() const;
   void makeEmpty();
   bool insert( ItemType newItem);
   bool retrieve( ItemType searchItem, ItemType & foundItem );
   bool deleteItem (ItemType deleteItem);
   void print();

private:

   TreeNode< ItemType > * rootPtr;  // pointer to the root

   //utility functions 
   void printHelper( TreeNode< ItemType > * );
   bool insertHelper(TreeNode< ItemType > * & node, ItemType item);
   bool deleteHelper( TreeNode< ItemType > * & , ItemType );
   void deleteNode( TreeNode<ItemType > * & );
   bool retrieveHelper( ItemType, TreeNode< ItemType > * & , ItemType & );

};

template<class ItemType>
Tree<ItemType>::Tree()
{
    rootPtr = NULL;
}
template<class ItemType>
Tree<ItemType>::~Tree()
{
    makeEmpty();
}
template<class ItemType>
bool Tree<ItemType>::isEmpty() const
//Returns True if the tree is empty, otherwise returns false
//Postcondition: Tree is unchanged.
{
    if(rootPtr == NULL)
    {
        return true;
    }
    else
    {
        return false;
    }
}
template<class ItemType>
void Tree<ItemType>::makeEmpty()
 //Makes the tree empty if it is not empty already.
 //Preconditions:  The tree exists.
//Postconditions: Tree is now empty. Any dynamically allocated memory which is no longer used is returned to the system. 
{
    return;
}
template<class ItemType>
bool Tree<ItemType>::insert( ItemType newItem)
// Inserts a copy of newItem in the tree.
//Precondition: The tree exists and has binary search property.
//Postcondition: if the tree already has an item where item == newItem, the function returns false and the trre is unchanged.
//Otherwise, the newItem is inserted in the tree preserving and the binary search property is maintained.
{
    if(rootPtr == NULL)
    {
        rootPtr->data = newItem;

        return true;
    }
    else
    {
        return insertHelper(rootPtr, newItem);
    }
}
template<class ItemType>
bool insertHelper( TreeNode< ItemType > * & node, ItemType item)
{
    if( item < node->data)//left
    {
        if(node->leftPtr == NULL)
        {
            node->leftPtr = new TreeNode<ItemType>(item);
            return true;
        }
        else
        {
            return insertHelper(node->leftPtr,item);
        }
    }
    else if(node->data < item)//right
    {
        if(node->righChild == NULL)
        {
            node->rightPtr = new TreeNode<ItemType>(item);
            return true;
        }
        else
        {
            return insertHelper(node->rightPtr,item);
        }
    }
    else// same value
    {
        return false;
    }
}
template<class ItemType>
bool Tree<ItemType>::retrieve( ItemType searchItem, ItemType & foundItem )
// Given a searchItem, it tries to retrieve as foundItem, an item in the tree where the item == searchItem. 
// Precondition:The tree exists and has the binary search property.
// Postcondition: If the tree already has an item where item == searchItem, foundItem is set to that item, and the function returns true.
//   If the tree has no such item, the function returns false and foundItem remains unchanged.  The tree is unchanged.
{

}
template<class ItemType>
bool Tree<ItemType>::deleteItem (ItemType deleteItem)
// Given a deleteItem, it deltes from the tree any item where item == deleteItem.
// Precondition: Tree exists and has binary search property.
// Postcondition: If the tree has an item where item == deleteItem, that item is removed from the tree, and the function returns true, and
// the binary search property is maintained. If the tree has no such item, the function returns false and the tree remains unchanged.
{

}
template<class ItemType>
void Tree<ItemType>::print()
// Prints the items in the tree in ascending order to the screen
// Precondition: The tree exists and has binary search property.
// Postcondition: The items have been printed in ascending order and the tree is unchanged
{

}
template<class ItemType>
void printHelper( TreeNode< ItemType > * )
{

}
template<class ItemType>
bool deleteHelper( TreeNode< ItemType > * & , ItemType )
{

}
template<class ItemType>
void deleteNode( TreeNode<ItemType > * & )
{

}
template<class ItemType>
bool retrieveHelper( ItemType, TreeNode< ItemType > * & , ItemType & )
{

}

-treenode -treenode

#ifndef TREENODE_H
#define TREENODE_H

template< class ItemType > class Tree;  // forward declarations

template<class ItemType>
class TreeNode {
   friend class Tree< ItemType >; // make Tree a friend

public:
   TreeNode( ItemType );  // constructor
   TreeNode();                  // constructor with data uninitialized 
   ItemType getData() const;      // return data in the node
private:
   ItemType data;                 
   TreeNode< ItemType > *leftPtr; 
   TreeNode< ItemType > *rightPtr;
};

// Constructor
template<class ItemType>
TreeNode< ItemType >::TreeNode( ItemType newItem )
{ 
    data = newItem;
    leftPtr = NULL;
    rightPtr = NULL;
}

template<class ItemType>
TreeNode< ItemType >::TreeNode( )
{ 
    leftPtr = NULL;
    rightPtr = NULL;
}


// Return a copy of the data in the node
template< class ItemType >
ItemType TreeNode< ItemType >::getData() const 
{ 
    return data; 
}

#endif

Heh. h The problem is that you forgot the scoping qualifier Tree<ItemType>:: in front of the function name for insertHelper. 问题在于您忘记了insertHelper的函数名称前面的作用域限定符Tree <ItemType> ::

Just do this: 只要这样做:

template<class ItemType>
bool Tree<ItemType>::insertHelper( TreeNode< ItemType > * & node, ItemType item)

By the way, the linker error should suggest to you that this is the problem. 顺便说一句,链接器错误应该提示您这是问题所在。 First of all, you know that you have a link problem, not a compile problem. 首先,您知道自己有链接问题,而不是编译问题。 Second, you know the symbol that can't be found is * Tree<ItemType>:: *insertHelper(...). 其次,您知道找不到的符号是* Tree <ItemType> :: * insertHelper(...)。 Third, you know that a call to that function was successfully compiled in Tree<ItemType>::insert, which means the compiler found and parsed the declaration for the insertHelper method without problem. 第三,您知道在Tree <ItemType> :: insert中成功编译了对该函数的调用,这意味着编译器可以找到并解析insertHelper方法的声明 The only possible explanation for the linker not being able to find the actual object code for the method is that the definition of the function either doesn't exist or doesn't have the same name that you declared it as! 链接器无法找到该方法的实际目标代码的唯一可能解释是,该函数的定义不存在或名称与声明时的名称相同!

Here: 这里:

if(rootPtr == NULL)
{
    rootPtr->data = newItem;

    return true;
}

If rootPtr is NULL then rootPtr->data is not valid. 如果rootPtr为NULLrootPtr->data无效。

Maybe you meant: 也许你的意思是:

if(rootPtr == NULL)
{
    rootPtr = new TreeNode<ItemType>(newItem);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM