2013-12-18 104 views
-1

我得到一個奇怪的錯誤,關於沒有匹配函數我甚至沒有調用函數。這裏的錯誤:C++。對象是用錯誤的構造函數實例化的?

BinarySearchTree.h:18:45: error: no matching function for call to ‘BinaryTree<int>::BinaryTree()’ BinarySearchTree<T>::BinarySearchTree(T elem)

顯然,這不是發現功能,因爲我沒有它在那裏。我沒有在那裏,因爲它實例化一個完全空的二叉樹是非常沒有意義的(或者至少對我來說似乎是這樣)。我也意識到有那些庫中有這些數據結構。我只是這樣做來幫助我學習數據結構類中的材料,並學習更多關於C++的知識,直到最近,我一直只用作「帶類的C」。我不明白爲什麼編譯器要求我爲那個構造函數,如果我不想在那裏。

這是源文件。我沒有用默認的構造函數實例化樹,這讓我感到非常困惑。另外,preorder方法在基類中完美工作,所以它應該與派生類一起工作(我只是讓派生類添加特定於二叉搜索樹的方法,但它仍然是二叉樹)。

#include "../headers/BinarySearchTree.h" 
#include <cstdio> 

void print_int_node(BTreeNode<int>* tgt) 
{ 
    printf("%d, ", tgt->getElement()); 
} 

int main(int argc, char* argv[]) 
{ 
    BinarySearchTree<int> myTree(5); 

    printf("Pre-order: \n"); 
    myTree.preorder(myTree.root, print_int_node); 
    printf("\n"); 

    return 0; 
} 

下面是我使用的類:

BinarySearchTree.h:

#ifndef _BINARY_SEARCH_TREE_H_ 
#define _BINARY_SEARCH_TREE_H_ 

#include "BinaryTree.h" 

template <typename T> 
class BinarySearchTree : public BinaryTree<T> { 
    void _add(BTreeNode<T>*, T elem); 

    public: 
     BinarySearchTree(T); 

     void add(T); 
}; 

template <typename T> 
BinarySearchTree<T>::BinarySearchTree(T elem) 
{ 
    this->root = new BTreeNode<T>(elem); 
} 

template <typename T> 
void BinarySearchTree<T>::add(T elem) 
{ 

} 

/***PRIVATE HELPER FUNCTIONS***/ 
template <typename T> 
void BinarySearchTree<T>::_add(BTreeNode<T>* n, T elem) 
{ 
    if(elem >= n->getElement()){ 
     if(n->getRightChild() != NULL){ 
      _add(n->getRightChild(), elem); 
     }else{ 
      n->setRightChild(new BTreeNode<T>(elem)); 
     } 
    }else{ 
     if(n->getLeftChild() != NULL){ 
      _add(n->getLeftChild(), elem); 
     }else{ 
      n->setLeftChild(new BTreeNode<T>(elem)); 
     } 
    } 
} 

#endif //_BINARY_SEARCH_TREE_H_ 

BinaryTree.h:

#ifndef _BINARY_TREE_H_ 
#define _BINARY_TREE_H_ 

#include "BTreeNode.h" 

template <typename T> 
class BinaryTree { 
    public: 
     BTreeNode<T>* root; 

     BinaryTree(T); 

     //traversals 
     void preorder(BTreeNode<T>*, void (*func)(BTreeNode<T>*)); 
     void inorder(BTreeNode<T>*, void (*func)(BTreeNode<T>*)); 
     void postorder(BTreeNode<T>*, void (*func)(BTreeNode<T>*)); 
}; 

template <typename T> 
BinaryTree<T>::BinaryTree(T elem) 
{ 
    root = new BTreeNode<T>(elem); 
} 

template <typename T> 
void BinaryTree<T>::preorder(BTreeNode<T>* node, void (*func)(BTreeNode<T>*)) 
{ 
    if(node == NULL) 
     return; 

    func(node); 
    preorder(node->getLeftChild(), func); 
    preorder(node->getRightChild(), func); 
} 

template <typename T> 
void BinaryTree<T>::inorder(BTreeNode<T>* node, void (*func)(BTreeNode<T>*)) 
{ 
    if(node == NULL) 
     return; 

    inorder(node->getLeftChild(), func); 
    func(node); 
    inorder(node->getRightChild(), func); 
} 

template <typename T> 
void BinaryTree<T>::postorder(BTreeNode<T>* node, void (*func)(BTreeNode<T>*)) 
{ 
    if(node == NULL) 
     return; 

    postorder(node->getLeftChild(), func); 
    postorder(node->getRightChild(), func); 
    func(node); 
} 
#endif //_BINARY_TREE_H_ 

BTreeNode.h:

#ifndef _B_TREE_NODE_H_ 
#define _B_TREE_NODE_H_ 

#define NULL 0 

template <typename T> 
class BTreeNode { 
    T element; 
    BTreeNode<T>* left; 
    BTreeNode<T>* right; 

    public: 
     BTreeNode(T); 
     BTreeNode(T, BTreeNode<T>*, BTreeNode<T>*); 
     ~BTreeNode(); 

     T getElement(); 
     BTreeNode<T>* getLeftChild(); 
     BTreeNode<T>* getRightChild(); 

     void setElement(T elem); 
     BTreeNode<T>* setLeftChild(BTreeNode<T>*); 
     BTreeNode<T>* setRightChild(BTreeNode<T>*); 
}; 

template <typename T> 
BTreeNode<T>::BTreeNode(T elem) 
{ 
    element = elem; 
    left = NULL; 
    right = NULL; 
} 

template <typename T> 
BTreeNode<T>::BTreeNode(T elem, BTreeNode<T>* l, BTreeNode<T>* r) 
{ 
    element = elem; 
    left = l; 
    right = r; 
} 

template <typename T> 
BTreeNode<T>::~BTreeNode<T>() 
{ 
    left = NULL; 
    right = NULL; 
} 

template <typename T> 
T BTreeNode<T>::getElement() 
{ 
    return element; 
} 

template <typename T> 
BTreeNode<T>* BTreeNode<T>::getLeftChild() 
{ 
    return left; 
} 

template <typename T> 
BTreeNode<T>* BTreeNode<T>::getRightChild() 
{ 
    return right; 
} 

template <typename T> 
void BTreeNode<T>::setElement(T elem) 
{ 
    element = elem; 
} 

template <typename T> 
BTreeNode<T>* BTreeNode<T>::setLeftChild(BTreeNode<T>* l) 
{ 
    left = l; 
    return left; 
} 

template <typename T> 
BTreeNode<T>* BTreeNode<T>::setRightChild(BTreeNode<T>* r) 
{ 
    right = r; 
    return right; 
} 
#endif //_B_TREE_NODE_H_ 
+0

這不是問題,但是以實線(編譯器及其標頭)保留以大寫字母('_BINARY_SEARCH_TREE_H_','_BINARY_TREE_H_','_B_TREE_NODE_H_')開頭的名稱。不要使用它們。 –

+2

'#define NULL 0'是放在任何地方的可怕的事情,尤其是頭部。 NULL已經是許多標準頭文件中的一個宏。 – chris

回答

6

其實你是在叫它。

在你的構造上BinarySearchTree

template <typename T> 
BinarySearchTree<T>::BinarySearchTree(T elem) 
{ 
    this->root = new BTreeNode<T>(elem); 
} 

你最好不要讓父類的構造函數的顯式調用,所以它使用默認值。您需要這樣做:

template <typename T> 
BinarySearchTree<T>::BinarySearchTree(T elem) : BinaryTree(elem) 
{ 
    this->root = new BTreeNode<T>(elem); 
} 

使用您的初始化程序列表!

作爲一個側面說明,這也將導致你泄漏內存,因爲這兩個構造函數初始化成員root用自己的new BTreeNode...

副本你也應該在構造函數在繼承的情況下是如何工作的閱讀起來。

+0

不妨在這裏有兩個。 – chris

+0

如果我只是實例化一個對象,爲什麼會有兩個初始化? – Hugo

+0

你從具有'BinarySearchTree'的'BinaryTree'繼承。這兩個構造函數都被調用。 – Collin

1

Class BinaryTree沒有默認的構造函數,它從BinarySearchTree的構造函數中調用,因爲BinaryTree是BinarySearchTree的基類。

相關問題