2012-09-24 60 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的成員函數的同一個文件中,或者將成員函數放置在聲明該類的頭文件中。