2012-09-24 99 views
0

可能重复:
Why can templates only be implemented in the header file?未定义参考 '类<Type> ::类'

我碰到了这面墙前,但我不知道如何解决它。在G ++我得到这个错误,每当我试图创建类二叉树的对象:

/home/bej0843/cs261/Assignment1/main.cpp:9: undefined reference to `BinaryTree<char>::BinaryTree()' 

下面是头文件中的代码:

#ifndef BINARYTREE_H 
#define BINARYTREE_H 
#include <iostream> 
#include <cstring> 
#include <stack> 
using namespace std; 



template<typename Type> 
class BinaryTree 
{ 
    public: 
     struct TreeNode 
     { 
       Type nodeinfo; 
       BinaryTree<Type> *left; 
       BinaryTree<Type> *right; 
     }; 
     BinaryTree(); 
     void setInfo(Type a); 
     void setSubtree(Type a); 
     bool isEmpty(); 
     Type Info(); 
     void inOrder(); 
     void preOrder(); 
     void postOrder(); 
     virtual ~BinaryTree(); 
    protected: 
     TreeNode *root; 
     stack<TreeNode*> s; 
     stack<TreeNode*> temp; 
    private: 
     void postOrder(TreeNode *r); 
}; 


#endif /* BINARYTREE_H */ 

下面是其实现代码:

#include "BinaryTree.h" 

template <typename Type> 
BinaryTree<Type>::BinaryTree(){ 

    root = NULL; 
} 

template <typename Type> 
void BinaryTree<Type>::setInfo(Type a){ 
    root->nodeinfo = a; 
    root->left = NULL; 
    root->right = NULL; 
    s.push(root); 
} 

template <typename Type> 
void BinaryTree<Type>::setSubtree(Type a){ 
    root->nodeinfo = a; 
    root->left->root = s.top(); 
    s.pop(); 
    root->right->root = s.top(); 
    s.pop(); 
    s.push(root); 
} 

template <typename Type> 
bool BinaryTree<Type>::isEmpty(){ 
    return (root==NULL); 
} 

template <typename Type> 
Type BinaryTree<Type>::Info(){ 
    return root->nodeinfo; 
} 

template <typename Type> 
void BinaryTree<Type>::inOrder(){ 

    TreeNode *c; 
    c = s.top(); 

    while (c!=NULL || (!temp.empty())){ 
    if (c!=NULL) 
    { 
    temp.push(c); 
    c = c->left; 
    } 
    else{ 
     c = temp.top(); 
     temp.pop(); 
     cout << c->nodeinfo +" "; 
     c = c->right; 
    } 
    } 

} 

template <typename Type> 
void BinaryTree<Type>::postOrder(){ 
    postOrder(s.top()); 
} 

template <typename Type> 
void BinaryTree<Type>::postOrder(TreeNode *r){ 
    temp.push(s.top()); 
    TreeNode *c = temp.top(); 
    s.pop(); 
    postOrder(c->left->root); 
    postOrder(c->right->root); 
    cout << c->nodeinfo + " "; 

} 

template <typename Type> 
void BinaryTree<Type>::preOrder(){ 
    TreeNode*c = s.top(); 
    while (c!=NULL||(!temp.empty())){ 
    if (c!=NULL){ 
     cout << c->nodeinfo + " "; 
     temp.push(c); 
     c=c->left; 
    } 
    else{ 
     c=temp.top(); 
     temp.pop(); 
     c=c->right; 
    } 
    } 
} 

template <typename Type> 
BinaryTree<Type>::~BinaryTree(){ 

} 

在主我打电话:

BinaryTree<char> tree; 

并获取错误。帮帮我?

回答

3

在使用模板类时,您必须将类的实现和声明放在同一个文件中。

编译器需要在使用模板类的相同位置生成代码。

Dynamic Allocation in Template Class Constructor

你可以不喜欢这样。

template <typename T> 
class myClass 
{ 
    //public and private interface. 
} ; 

//Here the implementation of the interface goes, just beneath the declaration. 
+0

这是行得通!这让我想知道为什么我的教授说他偏爱实施是在一个单独的文件中。谢谢您的帮助。 –

0

该错误表示链接程序未找到该类型的构造函数的定义。模板化代码中的主要原因是函数的定义(在这种情况下为构造函数)在实例化的地方不可用,也没有执行明确的实例化。简单的解决方案是在标题中提供模板的定义以使其可用。

1

当你写这样

template <typename Type> 
BinaryTree<Type>::BinaryTree(){ 

    root = NULL; 
} 

编译模板化的功能实际上并没有产生该功能的代码,直到它看到的模板参数的实例。

这就是为什么没有BinaryTree<char>::BinaryTree();编译器从来没有为此生成代码!原因是您的实例位于定义此模板函数的位置的单独编译单元(目标文件)中。

要解决此问题,请将您的main()函数放在定义所有BinaryTree的成员函数的同一个文件中,或者将成员函数放置在声明该类的头文件中。