C ++。用错误的构造函数实例化对象?

时间:2013-12-18 19:29:57

标签: c++ class inheritance constructor

我得到一个奇怪的错误,关于我甚至没有调用的函数没有匹配函数。这是错误:

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

显然它找不到那个功能,因为我没有它。我没有它,因为实例化一个完全空的二叉树(或者至少对我来说似乎是这样)是没有意义的。我也意识到有些库中有这些数据结构。我只是这样做是为了帮助学习我的数据结构类中的材料以及了解更多关于C ++的知识,直到最近我才将其用作“C with classes”。我无法理解为什么编译器要求我提供该构造函数,如果我不想在那里。

这是源文件。我没有使用默认构造函数实例化树,这让我非常困惑。此外,preorder方法在基类中完美地工作,因此它应该与派生类一起工作(我只是使派生类添加特定于二叉搜索树的方法,但它仍然是二叉树)。 / p>

#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_

2 个答案:

答案 0 :(得分: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...

您还应该了解构造函数在继承情况下的工作方式。

答案 1 :(得分:1)

类BinaryTree没有从BinarySearchTree的构造函数调用的默认构造函数,因为BinaryTree是BinarySearchTree的基类。