2011-04-14 58 views
0

嗨我每次在下面的代碼中聲明函數時都會收到錯誤消息error: expected initializer before '<' token。我不是很熟悉C++中的模板,所以這個錯誤真的讓我感到厭倦。我已經嘗試使用typename關鍵字,但它沒有奏效。任何幫助都會很棒。C++中的模板類

BinarySearchTree.h

 #ifndef BINARY_SEARCH_TREE_H_ 
     #define BINARY_SEARCH_TREE_H_ 

     #include "dsexceptions.h" 
     #include <iostream.h>  // For NULL 

      // Binary node and forward declaration because g++ does 
      // not understand nested classes. 
     template <class Comparable> 
     class BinarySearchTree; 

     template <class Comparable> 
     class BinaryNode 
     { 
      Comparable element; 
      BinaryNode *left; 
      BinaryNode *right; 

      BinaryNode(const Comparable & theElement, BinaryNode *lt, BinaryNode *rt) 
       : element(theElement), left(lt), right(rt) { } 
      friend class BinarySearchTree<Comparable>; 
     }; 


     // BinarySearchTree class 
     // 
     // CONSTRUCTION: with ITEM_NOT_FOUND object used to signal failed finds 
     // 
     // ******************PUBLIC OPERATIONS********************* 
     // void insert(x)  --> Insert x 
     // void remove(x)  --> Remove x 
     // Comparable find(x) --> Return item that matches x 
     // Comparable findMin() --> Return smallest item 
     // Comparable findMax() --> Return largest item 
     // boolean isEmpty()  --> Return true if empty; else false 
     // void makeEmpty()  --> Remove all items 
     // void printTree()  --> Print tree in sorted order 

     template <class Comparable> 
     class BinarySearchTree 
     { 
      public: 
      explicit BinarySearchTree(const Comparable & notFound); 
      BinarySearchTree(const BinarySearchTree & rhs); 
      ~BinarySearchTree(); 

      const Comparable & findMin() const; 
      const Comparable & findMax() const; 
      const Comparable & find(const Comparable & x) const; 
      bool isEmpty() const; 
      void printTree() const; 

      void makeEmpty(); 
      void insert(const Comparable & x); 
      void remove(const Comparable & x); 

      const BinarySearchTree & operator=(const BinarySearchTree & rhs); 

      private: 
      BinaryNode<Comparable> *root; 
      const Comparable ITEM_NOT_FOUND; 

      const Comparable & elementAt(BinaryNode<Comparable> *t) const; 

      void insert(const Comparable & x, BinaryNode<Comparable> * & t) const; 
      void remove(const Comparable & x, BinaryNode<Comparable> * & t) const; 
      BinaryNode<Comparable> * findMin(BinaryNode<Comparable> *t) const; 
      BinaryNode<Comparable> * findMax(BinaryNode<Comparable> *t) const; 
      BinaryNode<Comparable> * find(const Comparable & x, BinaryNode<Comparable> *t) const; 
      void makeEmpty(BinaryNode<Comparable> * & t) const; 
      void printTree(BinaryNode<Comparable> *t) const; 
      BinaryNode<Comparable> * clone(BinaryNode<Comparable> *t) const; 
     }; 

     #include "BinarySearchTree.cpp" 
     #endif 

BinarySearchTree.cpp

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

     /** 
     * Implements an unbalanced binary search tree. 
     * Note that all "matching" is based on the < method. 
     */ 

     /** 
     * Construct the tree. 
     */ 
     template <class Comparable> 
     BinarySearchTree<Comparable>::BinarySearchTree(const Comparable & notFound) : 
      root(NULL), ITEM_NOT_FOUND(notFound) 
     { 
     } 


     /** 
     * Copy constructor. 
     */ 
     template <class Comparable> 
     BinarySearchTree<Comparable>:: 
     BinarySearchTree(const BinarySearchTree<Comparable> & rhs) : 
      root(NULL), ITEM_NOT_FOUND(rhs.ITEM_NOT_FOUND) 
     { 
      *this = rhs; 
     } 

     /** 
     * Destructor for the tree. 
     */ 
     template <class Comparable> 
     BinarySearchTree<Comparable>::~BinarySearchTree() 
     { 
      makeEmpty(); 
     } 

     /** 
     * Insert x into the tree; duplicates are ignored. 
     */ 
     template <class Comparable> 
     void BinarySearchTree<Comparable>::insert(const Comparable & x) 
     { 
      insert(x, root); 
     } 

     /** 
     * Remove x from the tree. Nothing is done if x is not found. 
     */ 
     template <class Comparable> 
     void BinarySearchTree<Comparable>::remove(const Comparable & x) 
     { 
      remove(x, root); 
     } 


     /** 
     * Find the smallest item in the tree. 
     * Return smallest item or ITEM_NOT_FOUND if empty. 
     */ 
     template <class Comparable> 
     const Comparable & BinarySearchTree<Comparable>::findMin() const 
     { 
      return elementAt(findMin(root)); 
     } 

     /** 
     * Find the largest item in the tree. 
     * Return the largest item of ITEM_NOT_FOUND if empty. 
     */ 
     template <class Comparable> 
     const Comparable & BinarySearchTree<Comparable>::findMax() const 
     { 
      return elementAt(findMax(root)); 
     } 

     /** 
     * Find item x in the tree. 
     * Return the matching item or ITEM_NOT_FOUND if not found. 
     */ 
     template <class Comparable> 
     const Comparable & BinarySearchTree<Comparable>:: 
           find(const Comparable & x) const 
     { 
      return elementAt(find(x, root)); 
     } 

     /** 
     * Make the tree logically empty. 
     */ 
     template <class Comparable> 
     void BinarySearchTree<Comparable>::makeEmpty() 
     { 
      makeEmpty(root); 
     } 

     /** 
     * Test if the tree is logically empty. 
     * Return true if empty, false otherwise. 
     */ 
     template <class Comparable> 
     bool BinarySearchTree<Comparable>::isEmpty() const 
     { 
      return root == NULL; 
     } 

     /** 
     * Print the tree contents in sorted order. 
     */ 
     template <class Comparable> 
     void BinarySearchTree<Comparable>::printTree() const 
     { 
      if(isEmpty()) 
       cout << "Empty tree" << endl; 
      else 
       printTree(root); 
     } 

     /** 
     * Deep copy. 
     */ 
     template <class Comparable> 
     const BinarySearchTree<Comparable> & 
     BinarySearchTree<Comparable>:: 
     operator=(const BinarySearchTree<Comparable> & rhs) 
     { 
      if(this != &rhs) 
      { 
       makeEmpty(); 
       root = clone(rhs.root); 
      } 
      return *this; 
     } 

     /** 
     * Internal method to get element field in node t. 
     * Return the element field or ITEM_NOT_FOUND if t is NULL. 
     */ 
     template <class Comparable> 
     const Comparable & BinarySearchTree<Comparable>:: 
     elementAt(BinaryNode<Comparable> *t) const 
     { 
      if(t == NULL) 
       return ITEM_NOT_FOUND; 
      else 
       return t->element; 
     } 

     /** 
     * Internal method to insert into a subtree. 
     * x is the item to insert. 
     * t is the node that roots the tree. 
     * Set the new root. 
     */ 
     template <class Comparable> 
     void BinarySearchTree<Comparable>:: 
     insert(const Comparable & x, BinaryNode<Comparable> * & t) const 
     { 
      if(t == NULL) 
       t = new BinaryNode<Comparable>(x, NULL, NULL); 
      else if(x < t->element) 
       insert(x, t->left); 
      else if(t->element < x) 
       insert(x, t->right); 
      else 
       ; // Duplicate; do nothing 
     } 

     /** 
     * Internal method to remove from a subtree. 
     * x is the item to remove. 
     * t is the node that roots the tree. 
     * Set the new root. 
     */ 
     template <class Comparable> 
     void BinarySearchTree<Comparable>:: 
     remove(const Comparable & x, BinaryNode<Comparable> * & t) const 
     { 
      if(t == NULL) 
       return; // Item not found; do nothing 
      if(x < t->element) 
       remove(x, t->left); 
      else if(t->element < x) 
       remove(x, t->right); 
      else if(t->left != NULL && t->right != NULL) // Two children 
      { 
       t->element = findMin(t->right)->element; 
       remove(t->element, t->right); 
      } 
      else 
      { 
       BinaryNode<Comparable> *oldNode = t; 
       t = (t->left != NULL) ? t->left : t->right; 
       delete oldNode; 
      } 
     } 

     /** 
     * Internal method to find the smallest item in a subtree t. 
     * Return node containing the smallest item. 
     */ 
     template <class Comparable> 
     BinaryNode<Comparable> * 
     BinarySearchTree<Comparable>::findMin(BinaryNode<Comparable> *t) const 
     { 
      if(t == NULL) 
       return NULL; 
      if(t->left == NULL) 
       return t; 
      return findMin(t->left); 
     } 

     /** 
     * Internal method to find the largest item in a subtree t. 
     * Return node containing the largest item. 
     */ 
     template <class Comparable> 
     BinaryNode<Comparable> * 
     BinarySearchTree<Comparable>::findMax(BinaryNode<Comparable> *t) const 
     { 
      if(t != NULL) 
       while(t->right != NULL) 
        t = t->right; 
      return t; 
     } 

     /** 
     * Internal method to find an item in a subtree. 
     * x is item to search for. 
     * t is the node that roots the tree. 
     * Return node containing the matched item. 
     */ 
     template <class Comparable> 
     BinaryNode<Comparable> * 
     BinarySearchTree<Comparable>:: 
     find(const Comparable & x, BinaryNode<Comparable> *t) const 
     { 
      if(t == NULL) 
       return NULL; 
      else if(x < t->element) 
       return find(x, t->left); 
      else if(t->element < x) 
       return find(x, t->right); 
      else 
       return t; // Match 
     } 
/****** NONRECURSIVE VERSION************************* 
     template <class Comparable> 
     BinaryNode<Comparable> * 
     BinarySearchTree<Comparable>:: 
     find(const Comparable & x, BinaryNode<Comparable> *t) const 
     { 
      while(t != NULL) 
       if(x < t->element) 
        t = t->left; 
       else if(t->element < x) 
        t = t->right; 
       else 
        return t; // Match 

      return NULL; // No match 
     } 
*****************************************************/ 

     /** 
     * Internal method to make subtree empty. 
     */ 
     template <class Comparable> 
     void BinarySearchTree<Comparable>:: 
     makeEmpty(BinaryNode<Comparable> * & t) const 
     { 
      if(t != NULL) 
      { 
       makeEmpty(t->left); 
       makeEmpty(t->right); 
       delete t; 
      } 
      t = NULL; 
     } 

     /** 
     * Internal method to print a subtree rooted at t in sorted order. 
     */ 
     template <class Comparable> 
     void BinarySearchTree<Comparable>::printTree(BinaryNode<Comparable> *t) const 
     { 
      if(t != NULL) 
      { 
       printTree(t->left); 
       cout << t->element << endl; 
       printTree(t->right); 
      } 
     } 

     /** 
     * Internal method to clone subtree. 
     */ 
     template <class Comparable> 
     BinaryNode<Comparable> * 
     BinarySearchTree<Comparable>::clone(BinaryNode<Comparable> * t) const 
     { 
      if(t == NULL) 
       return NULL; 
      else 
       return new BinaryNode<Comparable>(t->element, clone(t->left), clone(t->right)); 
     } 
+2

爲什麼在你的.h結尾包含cpp? – geekazoid 2011-04-14 17:05:10

+3

哪一行錯誤指向?告訴我們錯誤消息指向的行/代碼。 – Nawaz 2011-04-14 17:10:02

+0

@geekazoid因爲語言需要它。 – 2011-04-14 17:44:42

回答

0

到Template你沒有在你的.h文件來定義函數的類。你也不能在.cpp文件中定義它們。我總是這樣做的,就是像通常那樣在.h文件中定義模板類。然後將函數定義寫入.hpp文件中。

.h文件會被寫成這樣:

#ifndef MYCLASS_H 
#define MYCLASS_H 

template<typename T> class MyClass 
{ 
public: 
    int MyFunction(); 
} 
#include "MyClass.hpp" 
#endif 

確保您在您的.h文件中的.HPP文件,而不是周圍的其他方式。

那麼你.HPP文件將是這樣的:

template<typename T> 
int MyClass::MyFunction() 
{ 
    ... 
} 

確保您範圍的功能,並且不包括在.HPP .h文件。編譯器會對你生氣。

這與在.h文件中定義函數基本相同,但是這允許您保留兩個獨立的文件。如果你的班級很小,功能很少,或者大部分功能都是一班,即。 getter/setter函數。爲此可能不值得爲其製作一個完整的文件,但在BST和AVL等情況下,擁有多個文件是非常好的,因此您不會盯着代碼牆。

+1

這些只是命名約定。我來自一個受g ++影響的Unix世界,我的「頭文件」文件以'.hh'結尾,模板的實際實現在'.tcc'中。其他的則有其他的約定,但在'.cpp'中定義模板函數肯定沒有問題,前提是你不要編譯它,並且'.cpp'中包含的頭文件不會造成任何傷害;包括警衛確保。 – 2011-04-14 18:08:22

+0

是的,現在我明白#inlcude .cpp是在底部。它的目的是讓你只在驅動程序中包含.h文件,而編譯器可以將其他人聯繫起來。謝謝你這樣做。只是你知道,我確實保持它爲.cpp,只要我不試圖編譯.cpp兩次就可以正常工作 – tpar44 2011-04-14 18:28:58