模板类返回“不命名类型”

时间:2013-04-29 03:37:34

标签: c++ class templates types

感谢您查看此内容。我知道我错过了一些非常明显的东西,但我现在已经被困在这个错误上两个小时了。基本上,当我编译我的类时,这就是返回的内容:

生成文件

全部:主要测试

main:testbintree.cpp bintree.cpp bintree.h treenode.h     g ++ -o main testbintree.cpp

调用'make':

g++ -o test bintree.cpp
bintree.cpp:2:1: error: ‘BinTree’ does not name a type
bintree.cpp:8:1: error: expected unqualified-id before ‘template’
bintree.cpp:16:1: error: ‘BinTree’ does not name a type
bintree.cpp:21:1: error: expected unqualified-id before ‘template’
bintree.cpp:43:13: error: expected initializer before ‘<’ token
bintree.cpp:73:13: error: expected initializer before ‘<’ token
bintree.cpp:117:11: error: expected initializer before ‘<’ token
bintree.cpp:131:11: error: expected initializer before ‘<’ token
bintree.cpp:143:11: error: expected initializer before ‘<’ token
bintree.cpp:168:11: error: expected initializer before ‘<’ token
bintree.cpp:193:13: error: expected initializer before ‘<’ token
bintree.cpp:202:13: error: expected initializer before ‘<’ token
bintree.cpp:210:13: error: expected initializer before ‘<’ token
bintree.cpp:218:1: error: ‘string’ in namespace ‘std’ does not name a type
bintree.cpp:225:1: error: expected unqualified-id before ‘template’
bintree.cpp:255:1: error: ‘TreeNode’ does not name a type
bintree.cpp:275:1: error: expected unqualified-id before ‘template’
bintree.cpp:288:1: error: ‘TreeNode’ does not name a type
bintree.cpp:308:1: error: expected unqualified-id before ‘template’
bintree.cpp:316:13: error: expected initializer before ‘<’ token
make: *** [test] Error 1

bintree.cpp

template <class T> 
BinTree<T>::BinTree() 
{
    thesize = 0;       // set the size to zero 
    root = NULL;      // root pointer to NULL 
}

template <class T> 
BinTree<T>::BinTree(const BinTree<T>& source) 
{
    root = copy(source.root, NULL);            // copy all the values in source 
    thesize = source.thesize;            // copy the size 
}

template <class T> 
BinTree<T>::~BinTree()
{
    dealloc(root);           // delete all the values in the tree
} 

template <class T>
T* BinTree<T>::Search(T& x) 
{
    TreeNode<T>* cur = root;      // set current to the root of the tree
    if(!cur)
        throw EmptyTreeError();    // if there was no root, throw an exception 

    while(cur)                    // while current isn't null 
    {
        if(*(cur->item) == x)      // check to see if current is the key that is being searched for
            return cur->item;       // return if so 

        else if(x < *(cur->item))   // otherwise, compare the current key with x 
            cur = cur->left;         // and go in the correct direction 
        else 
            cur = cur->right; 
    }

    throw ValueNotFoundError();    // if current got to NULL, then the value was not in the tree 
}

template <class T> 
void BinTree<T>::Insert(T* x) 
{
    TreeNode<T>* curPar = NULL;  // current parent; 
    TreeNode<T>* cur = root;     // current node; 

    while(cur)  // while current isn't null 
    {
        curPar = cur;         // set the current equal to the current parent in case the loop breaks 
        if(*x < *(cur->item)) // compare the current key with x 
            cur = cur->left;  // then go in the correct direction 
        else 
            cur = cur->right;   
    }

    // create the new TreeNode that will be inserted 
    TreeNode<T>* in = new TreeNode<T>(x, NULL, NULL, curPar); 

    if(!curPar)     // if current parent was NULL...
        root = in;   // we have had an empty tree, so set in to the root

    else if(*(in->item) < *(curPar->item)) // then just check which child in should be 
        curPar->left = in; 

    else 
        curPar->right = in; 

    thesize++;  // increment the size 
}

template <class T> 
void BinTree<T>::Delete(T& x) 
{   
    TreeNode<T>* y;
    TreeNode<T>* w;                  // y = new node to delete, x = the replacement child 
    TreeNode<T>* z = NodeSearch(x);      // original node to delete 

    if(!(z->left && z->right))         // decide which case we're dealing with
        y = z; 
    else 
    {
    // Since Search returns a T* instead of a Node, this is a quick alternative to writing a 
    // NodeSuccessor/Predecessor, although it does add in another log(n) time operation. 
        y = NodeSearch(*Successor(*(z->item))); 
    }

    // Find the replacement child (either left/right can be picked first, doesn't matter) 
    if(y->left)                 
        w = y->left;      
    else 
        w = y->right; 

    if(w)                            // if x is not NULL...
        w->parent = y->parent;        // change x's parent to y's parent 

    // Now assign the parent of y to point to x in the correct direction 
    if(!y->parent)                   // if y does not have a parent
        root = w;                     // then you must be replacing the root 
    else 
    {
        if(y == y->parent->left)      // otherwise check which child y was...
            y->parent->left = w;       // and then set y's parents pointer to x 
        else 
            y->parent->right = w; 
    }

    if(y != z)                 // swap the data if we we're in case 3
        z->item = y->item; 

    delete y;                 // now finally delete y 

    thesize--;                // decrement size 
}                                        

template <class T> 
T* BinTree<T>:: Maximum()   
{
    TreeNode<T>* cur = root; // set current equal to the root 

    while(cur->right)    // while you can go right, keep going 
        cur = cur->right; 

    if(cur)               // if you found a valid key, return it 
        return cur->item; 
    else 
        throw EmptyTreeError();  // otherwise the tree was empty, throw an exception 
}

template <class T> 
T* BinTree<T>:: Minimum()   // similar algorithm for minimum 
{
    TreeNode<T>* cur = root;

    while(cur->left) 
        cur = cur->left; 
    if(cur) 
        return cur->item; 
    throw EmptyTreeError(); 
}

template <class T> 
T* BinTree<T>::Successor(T& x)
{
    TreeNode<T>* cur = NodeSearch(x);  // first search for the node with key x 

    if(cur->right)     // if it has a right subtree...
    {   
        cur = cur->right;     // go the root of that subtree 
        while(cur->left)      // then search for the smallest key 
            cur = cur->left; 
        return cur->item;     // return the key when you find it 
    } 
    else         // if current did not have a right subtree... 
    {
        // search for the lowest ancestor of current whose left subtree contains current 
        while(cur->parent && cur != cur->parent->left)  
            cur = cur->parent; 

        if(cur->parent)     // if you found it, return it 
            return cur->parent->item; 
        else 
            throw NoSuccessorFoundError();  // otherwise there is no successor; throw an exception
    }
}

template <class T> 
T* BinTree<T>::Predecessor(T& x)   // similar algorithm to successor 
{
    TreeNode<T>* cur = NodeSearch(x);

    if(cur->left) 
    {   
        cur = cur->left; 
        while(cur->right) 
            cur = cur->right; 
        return cur->item; 
    } 
    else    
    {
        while(cur->parent && cur != cur->parent->right) 
            cur = cur->parent; 

        if(cur->parent) 
            return cur->parent->item; 
        else 
            throw NoPredecessorFoundError();
    }
} 

// All traversals rely on the helper method (along with str) 
template <class T> 
void BinTree<T>::InOrder()
{
    std::stringstream s;
    traverseHelp(s, root, 1);
    std::cout << s.str() << std::endl; 
}


template <class T> 
void BinTree<T>::PreOrder() 
{
    std::stringstream s;
    traverseHelp(s, root, 0);
    std::cout << s.str() << std::endl; 
}

template <class T> 
void BinTree<T>::PostOrder()
{
    std::stringstream s;
    traverseHelp(s, root, 2);
    std::cout << s.str()  << std::endl;
} 

template <class T> 
std::string BinTree<T>::str(int x)
{
    std::stringstream s;
    traverseHelp(s, root, x);; 
    return s.str(); 
} 

template <class T> 
void BinTree<T>::traverseHelp(std::stringstream &s, TreeNode<T>* cur, int order)
{
    if(cur) // if we have not hit a null value...
    {
    // check order for the correct traversal, and perform that traversal 
        if(!order) 
        {
            s << *(cur->item) << " ";           
            traverseHelp(s, cur->left, order);  
            traverseHelp(s, cur->right, order); 
        }
        else if(order == 1) 
        {

            traverseHelp(s, cur->left, order); 
            s <<  *(cur->item)  <<  " ";
            traverseHelp(s, cur->right, order);
        }
        else 
        {
            traverseHelp(s, cur->left, order); 
            traverseHelp(s, cur->right, order);
            s << *(cur->item) << " ";
        }
    }
} 

// Same as search, except returns a node. 
template <class T>
TreeNode<T>* BinTree<T>::NodeSearch(T& x) 
{
    TreeNode<T>* cur = root; 
    if(!cur)
        throw EmptyTreeError(); 

    while(cur)
    {
        if(*(cur->item) == x)
            return cur; 

        else if(x < *(cur->item))
            cur = cur->left; 
        else 
            cur = cur->right; 
    }

    throw ValueNotFoundError();
}

template <class T> 
void BinTree<T>::dealloc(TreeNode<T>* x)
{
    if(x)  // if not NULL 
    {
        dealloc(x->left);  // deallocate the left and right 
        dealloc(x->right);
        delete x;          // then delete the current node 
    } 
}


template <class T> 
TreeNode<T>* BinTree<T>::copy(TreeNode<T>* curSource, TreeNode<T>* prevPar)
{
    if(curSource) // if curSource is not NULL 
    {
        // create the copy of the current source node 
        TreeNode<T>* newNode = new TreeNode<T>(curSource->item, NULL, NULL, prevPar);

        newNode->left = copy(curSource->left, newNode);  // set its right and left recursively 
        newNode->right = copy(curSource->right, newNode);
        return newNode;   // then return the new node
    }
    else 
        return NULL;        // return NULL so the leaves' children can be set correctly 
}


//********** methods required just for the sort **********************
//***Note the unit test is essentially the sorting program
// Both methods work like InOrder 

template <class T> 
void BinTree<T>::arrayInOrder(T A[]) 
{
    int x = 0; 
    sortTraverse(root, A, x); 
}

template <class T> 
void BinTree<T>::sortTraverse(TreeNode<T>* cur, T A[], int& index) 
{
    if(cur) 
    {
        sortTraverse(cur->left, A, index);
        A[index] = *(cur->item); 
        index++;
        sortTraverse(cur->right, A, index); 
    }
} 

bintree.h

#ifndef BINTREE_H_
#define BINTREE_H_

#include "treenode.h"
#include<iostream> 
#include<sstream>


template <class T> 
class BinTree
{ 
    TreeNode<T>* root;                              // root of the tree 
    int thesize;                                    // int instead of size_t so that comparison with indices is less error-prone

 public:
                                        // Constructs an empty binary tree.
                                        // post: an empty binary tree has been constructed.  
    BinTree();   

                                        // Constructs a binary search with with the same T*s as source 
                                        // post: a binary search tree has been construced that is identical to source 
    BinTree(const BinTree<T>& source); 

                                        // Deconstructs the binary tree.
                                        // post: the binary tree has been deconstructed 
    ~BinTree();  

                                        // Returns true if the tree is empty, returns false otherwise. 
                                        // post: The bool indicating whether or not the tree is empty is returned. 
    bool isEmpty() { return !root;} 

                                        // Returns the first T with the same key value as x.
                                        // pre: x is of type T that has overloaded comparison operators; a T with key x is in the tree. 
                                        // post: A pointer to the first T with the same key value as x is returned. 
    T* Search(T& x);            

                                        // Inserts x into the binary tree. 
                                        // pre: x is of type T that has overloaded comparison operators.
                                        // post: x has been inserted into its proper place in the tree. 
    void Insert(T* x);  

                                        // Deletes the first T with the same key value as x. 
                                        // pre: x is of type T that has overloaded comparison operators.
                                        // post: The node containing the T with the same key value as x is now deleted. 
    void Delete(T& x); 

                                        // Returns the maximum of the binary search tree.
                                        // pre: the tree must contain at least one value. 
                                        // post: the T* with the maximum key is returned.
    T* Maximum(); 

                                        // Returns the minimum of the binary search tree.
                                        // pre: the tree must contain at least one value. 
                                        // post: the T* with the minimum key is returned.
    T* Minimum(); 

                                        // Returns the successor (next highest value) of x. 
                                        // pre: x's key is not the maximum of the tree; x is of type T that has overloaded comparison operators.
                                        // post: a pointer of the T with the key succeding x's key is returned.
    T* Successor(T& x); 

                                        // Returns predecessor (next lowest value) of x. 
                                        // pre: x's key is not the minimum of the tree;  x is of type T that has overloaded comparison operators.
                                        // post: a pointer of the T with the key preceding x's key is returned.
    T* Predecessor(T& x); 

                                        // Prints an in-order traversal of the tree to standard out.
                                        // post: an in-order traversal has been printed. 
    void InOrder(); 

                                        // Prints a pre-order traversal of the tree to standard out.
                                        // post: a pre-order traversal has been printed. 
    void PreOrder(); 

                                        // Prints a post-order traversal of the tree to standard out.
                                        // post: a post-order traversal has been printed. 
    void PostOrder(); 

                                        // Returns a string representing a traversal of the tree. 
                                        // x = 0 for pre-order, 1 for in-order, and 2 for post-order.
                                        // pre: 0 <= x <= 2. 
                                        // post: the correct traversal of the tree has been returned as a string.
    std::string str(int x);

                                        // Returns the length of the binary tree. 
                                        // post: the size is returned          
    int size() { return thesize; }

                                        // Sorts an array A with the same values that are in the tree. 
                                        // pre: the keys in the Ts in A must have the same values as A.
                                        // post: A is now in sorted order based on key value.
    void arrayInOrder(T A[]) ;

                                        // Does an in-order traversal of the tree and puts the values in array A 
                                        // pre: index must start off 0.
                                        // post: A now contains the in-order traversal of the tree 
    void sortTraverse(TreeNode<T>* cur, T A[], int& index) ;



 private:

                                        // Recursive algorithm that traverses the source tree and copies it. 
                                        // post: the binary search tree with root curSource has been copied. 
    TreeNode<T>* copy(TreeNode<T>* curSource, TreeNode<T>* prevPar);

                                        // The exact same as search, except it returns a node to help with methods like delete. 
                                        // pre:  x is of type T that has overloaded comparison operators; T with key x is in the tree. 
                                        // post: the TreeNode containing with item T with has key x is returned. 
    TreeNode<T>* NodeSearch(T& x); 

                                        // Deletes all the nodes in the tree with root x.
                                        // post: the tree with root x has been deleted from memory. 
    void dealloc(TreeNode<T>* x);

                                        // Helper recursive function that traverses the binary search tree. 
                                        // x = 0 for pre-order, 1 for in-order, and 2 for post-order.
                                        // pre: s must be an empty stringstream, 0 <= x <= 2. 
                                        // post: s now contains the correct traversal of the tree. 
    void traverseHelp(std::stringstream &s, TreeNode<T>* cur, int order);         

};

class EmptyTreeError{};                                 // max and min exception
class ValueNotFoundError{};                             // searching exception 
class NoSuccessorFoundError{};                          // successor exception 
class NoPredecessorFoundError{};                        // predecessor exception 

#include "bintree.cpp"                              //include this to make the template work
#endif 

treenode.h

#ifndef _NODE_H
#define _NODE_H
#include<cstdlib> 

template <class T> class BinTree;                       // so that we can make list a friend... and node knows its a template

template <class T> 
class TreeNode
{

    friend class BinTree<T>;                            // allow the binary tre to use the private data of Node 
    T* item;                                        // item stored in the Node 
    TreeNode<T>* left;                                  // left pointer 
    TreeNode<T>* right;                                 // right pointer 
    TreeNode<T>* parent;                                //  parent pointer


    public:
                                            // Constructs a new node, with value item, left pointer ileft, right pointer iright, parent  pointer ipar 
                                        // post: a new Treenode has been constructed 
        TreeNode(T* initem = 0, TreeNode<T>* ileft = NULL, TreeNode<T>* iright = NULL, TreeNode<T>* ipar = NULL )
        {
            item = initem;  
            left = ileft;
            right = iright;
            parent = ipar;
        }
};

#endif 

testbintree.cpp

# include "bintree.h"
# include<cassert> 


                                        //Test to make sure the constructor works (also makes sure that length and str work for empty lists).
void testConstructor() 
{
    BinTree<int> t;
    assert(t.str(1) == "");
    assert(t.size() == 0); 
} 


                                        // Test to make sure insertion works correctly. (along with size) 
void testInsertion() 
{
    BinTree<int> t;
    int* a = new int(3);
    int* b = new int(2);
   int* c = new int(0); 
    int* d = new int(1);
    int* e = new int(5);
    int* f = new int(4); 
   int* g = new int(6); 
    t.Insert(a); 
    t.Insert(b); 
    t.Insert(c); 
    t.Insert(d); 
    t.Insert(e); 
    t.Insert(f);
    t.Insert(g);

    assert(t.str(1)  == "0 1 2 3 4 5 6 "); 
    assert(t.size()  == 7); 

    delete a, b, c, d, e, f, g; 

}

                                        // Test to make sure isEmpty works
void testIsEmpty() 
{
    BinTree<int> t;
    assert(t.isEmpty());
    int* a = new int(3);
    int* b = new int(2);
    t.Insert(a); 
    t.Insert(b); 
    assert(!t.isEmpty());

    delete a, b; 
}

                                        // Test to make sure the copy constructor works in multiple cases.
void testCopyConstructor() 
{
    BinTree<int> t; 
    BinTree<int> w(t);  
                                        // See if it works for an empty tree 
    assert(w.str(1) == "");
    assert(w.size() == 0); 

                                        // Now test copying a more full tree
    int* a = new int(3);
    int* b = new int(2);
   int* c = new int(0); 
    int* d = new int(1);
    int* e = new int(5);
    int* f = new int(4); 
   int* g = new int(6); 
    t.Insert(a); 
    t.Insert(b); 
    t.Insert(c); 
    t.Insert(d); 
    t.Insert(e); 
    t.Insert(f);
    t.Insert(g);
    BinTree<int> z(t); 
    assert(z.str(1) == "0 1 2 3 4 5 6 ");
    assert(z.size() == 7); 

                                        //Now test deleting something and seeing if they are different
    int x = 5; 
    t.Delete(x); 
    assert(t.str(1) == "0 1 2 3 4 6 ");
    assert(z.str(1) == "0 1 2 3 4 5 6 ");
    x = 3; 
    assert(z.Successor(x) == f);

    delete a, b, c, d, e, f, g; 
}

                                        // Test to make sure that search at least finds the right value 
                                        // *Note: Search will be further tested in other methods (delete, max, etc..) 
void testSearch() 
{
    BinTree<int> t;
    int* a = new int(3);
    int* b = new int(2);
   int* c = new int(0); 
    int* d = new int(1);
    int* e = new int(5);
    t.Insert(a); 
    t.Insert(b); 
    t.Insert(c); 
    t.Insert(d); 
    t.Insert(e); 

    int x = 5; 
    assert(*(t.Search(x))  == 5 ); 

    delete a, b, c, d, e;
}

                                        // Test to make sure maximum works in multiple cases. 
void testMaximum() 
{
    BinTree<int> t;
    int* a = new int(3);
    int* b = new int(2);
   int* c = new int(0); 
    int* d = new int(1);
    int* e = new int(5);
    int* f = new int(4); 
   int* g = new int(6); 
    t.Insert(a); 
                                        // see if it works for a one element tree 
    assert(*(t.Maximum())  ==  3 );

    t.Insert(b); 
    t.Insert(c); 
    t.Insert(d); 
    t.Insert(e); 
    t.Insert(f);
    t.Insert(g);

                                        // see if it works for a more full tree 
    assert(*(t.Maximum())  ==  6);

    delete a, b, c, d, e, f, g; 
}

                                        // Test to make sure minimum works in multiple cases 
void testMinimum() 
{
    BinTree<int> t;
    int* a = new int(3);
    int* b = new int(2);
   int* c = new int(0); 
    int* d = new int(1);
    int* e = new int(5);
    int* f = new int(4); 
   int* g = new int(6); 
    t.Insert(a); 
    // see if it works for a one element tree 
    assert(*(t.Minimum())  ==  3);

    t.Insert(b); 
    t.Insert(c); 
    t.Insert(d); 
    t.Insert(e); 
    t.Insert(f);
    t.Insert(g);

    // see if it works for a more full tree 
    assert(*(t.Minimum())  ==  0);

    delete a, b, c, d, e, f, g; 
}

void testPredecessor() 
{
    BinTree<int> t;
    int* a = new int(3);
    int* b = new int(2);
   int* c = new int(0); 
    int* d = new int(1);
    int* e = new int(5);
    int* f = new int(4); 
   int* g = new int(6); 

    t.Insert(a); 
    t.Insert(b); 
    t.Insert(c); 
    t.Insert(d); 
    t.Insert(e); 
    t.Insert(f);
    t.Insert(g);

    int x = 3;
    assert(*(t.Predecessor(x)) == 2); 
    x = 1;                             // this tests the ancestor case 
    assert(*(t.Predecessor(x)) == 0); 
    x = 6;
    assert(*(t.Predecessor(x)) == 5); 

    delete a, b, c, d, e, f, g; 
}

                                        // Test to make sure successor works in multiple cases
void testSuccessor()
{
    BinTree<int> t;
    int* a = new int(3);
    int* b = new int(2);
   int* c = new int(0); 
    int* d = new int(1);
    int* e = new int(5);
    int* f = new int(4); 
   int* g = new int(6); 

    t.Insert(a); 
    t.Insert(b); 
    t.Insert(c); 
    t.Insert(d); 
    t.Insert(e); 
    t.Insert(f);
    t.Insert(g);

    int x = 3;
    assert(*(t.Successor(x)) == 4); 
    x = 2;                                              // this tests the ancestor case 
    assert(*(t.Successor(x)) == 3); 
    x = 5;
    assert(*(t.Successor(x)) == 6); 

    delete a, b, c, d, e, f, g; 

}

                                        // Tests delete in multiple cases. 
void testDelete() 
{
    BinTree<int> t;
    int* a = new int(3);
    int* b = new int(2);
   int* c = new int(0); 
    int* d = new int(1);
    int* e = new int(5);
    int* f = new int(4); 
   int* g = new int(6); 

    t.Insert(a); 
    t.Insert(b); 
    t.Insert(c); 
    t.Insert(d); 
    t.Insert(e); 
    t.Insert(f);
    t.Insert(g);

    int x = 1;                                              // test deleting a leaf 
    t.Delete(x);
    assert(t.str(1) == "0 2 3 4 5 6 ");
    x = 2;                                                  // test deleting a non-leaf without two nodes
    t.Delete(x); 
    assert(t.str(1) == "0 3 4 5 6 ");  
    x = 5;
    t.Delete(x);                                // test deleting a node with two children 
    assert(t.str(1) == "0 3 4 6 ");
    delete a, b, c, d, e, f, g; 
}

// Test all the traversal functions (using str(), but this also tests the standard out methods, as well). 
void testTraversals() 
{
    BinTree<int> t;
    int* a = new int(3);
    int* b = new int(2);
   int* c = new int(0); 
    int* d = new int(1);
    int* e = new int(5);
    int* f = new int(4); 
   int* g = new int(6); 

    t.Insert(a); 
    t.Insert(b); 
    t.Insert(c); 
    t.Insert(d); 
    t.Insert(e); 
    t.Insert(f);
    t.Insert(g);

    assert(t.str(0) == "3 2 0 1 5 4 6 ");
    assert(t.str(2) == "1 0 2 4 6 5 3 ");

    delete a, b, c, d, e, f, g; 
}

// Test all the methods together to make sure they linked up right. 
void testEverything() 
{
    BinTree<int> t;
    int* a = new int(5);
    int* b = new int(3);
   int* c = new int(1); 
    int* d = new int(7);
    int* e = new int(9);
    int* f = new int(4); 
   int* g = new int(6);
    int* h = new int(2);
    int* i = new int(8);
    int* j = new int(10);

    t.Insert(a); 
    t.Insert(b); 
    t.Insert(c); 
    t.Insert(d); 
    t.Insert(e); 
    t.Insert(f);
    t.Insert(g);
    t.Insert(h);
    t.Insert(i);
    t.Insert(j);

    assert(t.str(1) == "1 2 3 4 5 6 7 8 9 10 ");

    int x = 1;                             
    t.Delete(x);
    assert(t.str(1) == "2 3 4 5 6 7 8 9 10 ");
    x = 7;                                
    t.Delete(x); 
    assert(t.str(1) == "2 3 4 5 6 8 9 10 ");
    x = 5;                                
    t.Delete(x); 
    assert(t.str(1) == "2 3 4 6 8 9 10 ");


    x = 2;
    assert(*(t.Successor(x)) == 3); 
    x = 9;                             
    assert(*(t.Successor(x)) == 10); 
    x = 8;
    assert(*(t.Predecessor(x)) == 6);
    x = 4;                             
    assert(*(t.Predecessor(x)) == 3); 

    delete a, b, c, d, e, f, g, h, i, j;

}

// Test for memory leaks by running testEverything in a big for loop. 
void testMemoryLeaks() 
{
for(int i = 0; i < 1000000; i++) 
    testEverything();
}



// Do the tests.  
main()
{
    testConstructor();
    testInsertion();
    testIsEmpty();
    testSearch(); 
    testMaximum();
    testMinimum();
    testCopyConstructor();
    testPredecessor();
    testSuccessor(); 
    testDelete(); 
    testTraversals();
    testEverything();
    //testMemoryLeaks();

    return 0; 
}

我知道我98%那里,但我不知道我做错了什么造成了这个错误。谢谢!!!

3 个答案:

答案 0 :(得分:0)

您是否在bintree.cpp中忘了#include“bintree.h”?

答案 1 :(得分:0)

由于您在头文件中包含了cpp,因此您不会将cpp文件视为编译单元。所以这样做错误

g++ -o main bintree.cpp

只需从makefile中删除bintree.cpp,它就会编译。

此外,我认为在标题中包含cpp并不是一个好习惯。如果您编写模板类或函数,请将其定义保留在头文件中。

答案 2 :(得分:0)

一般来说,您必须在头文件中实现模板类。当我快速浏览您的代码时,您就有了这一行:

#include "bintree.cpp"                                  //include this to make the template work

如果确实包含此行,则应以这种方式编译:

g++ -c bintree.h
g++ -o tree bintree.h

希望有所帮助