C++中关于模板类定义失败的问题
问题:我已经在.cpp文件中对声明进行了定义,但是却报错undefined reference to `BTnode<int>::BTnode(int const&)'| ,这是为什么代码如下:
头文件:
//.h文件中,对二叉树结点类声明
#ifndef BTNODE_H_INCLUDED
#define BTNODE_H_INCLUDED
template <typename valType>
class BTnode
{
public:
//...
BTnode(const valType &val);
//...
private:
valType _val;
int _cnt;
BTnode* _lchild;
BTnode* _rchild;
};
#endif
源文件:
//.cpp文件中对BTnode(const valType &val) 进行定义
#include “BTnode.h”
template <typename valType>
inline BTnode<valType>::
BTnode(const valType &val):_val(val)
{
_cnt=1;
_lchild=_rchild=0;
}
main函数:
#include <iostream>
#include "BinaryTree.h"
#include "BTnode.h"
#include <string.h>
using namespace std;
int main()
{
BTnode<int> bt(3);
return 0;
}
程序报错:
undefined reference to `BTnode<int>::BTnode(int const&)'|
问题:我已经在.cpp文件中对声明进行了定义,但是却报错undefined reference to `BTnode<int>::BTnode(int const&)'| ,这是为什么? 有个问题,这个是BinaryTree.h 文件的内容?
源文件:
//.cpp文件中对BTnode(const valType &val) 进行定义
#include “BTnode.h”
template <typename valType>
inline BTnode<valType>::
BTnode(const valType &val):_val(val)
{
_cnt=1;
_lchild=_rchild=0;
} 人造人 发表于 2021-3-11 15:37
有个问题,这个是BinaryTree.h 文件的内容?
这个是我.BTnode.cpp文件的内容,用来对BTnode.h当中的所有类声明进行定义,在这里我只截取了一部分。 547658697 发表于 2021-3-11 15:40
这个是我.BTnode.cpp文件的内容,用来对BTnode.h当中的所有类声明进行定义,在这里我只截取了一部分。
把所有的源代码都贴出来,说明哪一个代码在哪一个源文件,我在这边帮你看看
人造人 发表于 2021-3-11 15:44
把所有的源代码都贴出来,说明哪一个代码在哪一个源文件,我在这边帮你看看
感谢!下面是我所有的代码,每个开头都标有文件名字,现在是测试BTnode模板实例化就出现了问题。
main.cpp
#include <iostream>
#include "BinaryTree.h"
#include "BTnode.h"
#include <string.h>
using namespace std;
template <typename elemType>
ostream& operator << (ostream &os, BinaryTree<elemType> &bt)
{
return bt.print(os);
}
int main()
{
BTnode<int> bt(3);
return 0;
}
BTnode.h
#ifndef BTNODE_H_INCLUDED
#define BTNODE_H_INCLUDED
template <typename Type>
class BinaryTree;
template <typename valType>
class BTnode
{
public:
friend class BinaryTree<valType>;
BTnode(const valType &val);
void insert_value( const valType &val);
void lchild_leaf(BTnode<valType> *leaf,BTnode<valType> *subtree );
void remove_value(valType &val , BTnode<valType> *prev);
private:
valType _val;
int _cnt;
BTnode* _lchild;
BTnode* _rchild;
};
#endif // BTNODE_H_INCLUDED
BTnode.cpp
#include "BTnode.h"
template <typename valType>
inline BTnode<valType>::
BTnode(const valType &val):_val(val)
{
_cnt=1;
_lchild=_rchild=0;
}
template <typename valType>
inline void BTnode<valType>::
insert_value ( const valType &val )
{
if(_val == val )
_cnt++;
if(_val < val)
{
if(! _lchild)
_lchild = new BTnode<valType>(val);
else
_lchild->insert_value(val);
}
if(_val > val)
{
if(! _rchild)
_rchild = new BTnode<valType>(val);
else
_rchild->insert_value(val);
}
}
template <typename valType>
inline void BTnode<valType>::
lchild_leaf(BTnode<valType> *leaf,BTnode<valType> *subtree )
{
//找到没有左孩子的结点
while (! subtree->_lchild )
subtree = subtree->_lchild;
//找到了 subtree所指结点没有左子树
subtree->_lchild = leaf;
}
template <typename valType>
inline void BTnode<valType>::
remove_value(valType &val , BTnode<valType> *prev)
{
if (val < _val)
{
if( !_lchild )
return ;
else
{
_lchild->remove_value(val,_lchild);
}
}
else
if (val > _val)
{
if( !_rchild )
return ;
else
{
_rchild->remove_value(val,_rchild);
}
}
else
{
if(_rchild)
{
prev = _rchild;
if(_lchild)
{
if(!prev -> _lchild )
prev->_lchild =_lchild;
else
BTnode<valType>::lchild_leaf(_lchild,prev->_lchild);
}
}
else
prev = _lchild;
delete this;
}
}
BinaryTree.h
#ifndef BINARYTREE_H_INCLUDED
#define BINARYTREE_H_INCLUDED
#include "BTnode.h"
#include <iostream>
using namespace std;
template <typename elemType>
class BinaryTree
{
public:
BinaryTree() ;
BinaryTree(const BinaryTree& );
~BinaryTree() ;
BinaryTree& operator = (const BinaryTree& );
ostream& print(ostream& os) const ; //中序遍历
void insert(const elemType &elem);
void remove( const elemType &elem);
void remove_root( const elemType &elem);
bool empty() {return _root;}
void clear();
private:
void clear(BTnode<elemType> *pt);
BTnode<elemType>* _root;
void copy(BTnode<elemType> *tar,BTnode<elemType> *src);
};
#endif // BINARYTREE_H_INCLUDED
BinaryTree.cpp
#include "BinaryTree.h"
template <typename elemType>
inline BinaryTree<elemType>::BinaryTree() :_root(0) {}
template <typename elemType>
inline BinaryTree<elemType>::BinaryTree(const BinaryTree &rhs)
{
copy(_root,rhs._root);
}
template <typename elemType>
inline BinaryTree<elemType>::~BinaryTree()
{
clear();
}
template <typename elemType>
inline BinaryTree<elemType>&
BinaryTree<elemType>::
operator =(const BinaryTree &rhs)
{
if(this != rhs)
clear();
copy(_root,rhs._root);
return *this;
}
template <typename elemType>
inline void BinaryTree<elemType>::
insert(const elemType &elem)
{
if( ! _root )
_root = new BTnode<elemType>(elem);
else
_root->inset_value(elem);
}
template <typename elemType>
inline void BinaryTree<elemType>::
remove(const elemType &elem)
{
if (_root)
{
if(_root->_val == elem)
remove_root();//删除根节点
else
_root->remove_value(elem , _root); // 删除_root二叉树中的值为elem的结点
}
}
template <typename elemType>
inline void BinaryTree<elemType>::
remove_root (const elemType &elem)
{
BTnode<elemType> *p = _root; //指向准备删除的根节点
if (! _root)
return ;
if (_root->_rchild)
{
_root = _root->_rchild;
if( _root->_lchild )
{
BTnode<elemType> *lc = p->_lchild;//指向待处理的根节点的左子树
BTnode<elemType> *newlc = _root->_lchild;//新根节点的左子树
if(! newlc)
_root->_rchild = lc;
else
BTnode<elemType>::lchild_leaf(lc ,newlc);
}
}
else
_root = p->_lchild;
delete p;
}
template <typename elemType>
inline void
BinaryTree<elemType>::
clear()
{
if(_root)
{
clear(_root);
_root = 0;
}
}
template<typename elemType>
inline void
BinaryTree<elemType>::
clear(BTnode<elemType> *pt)
{
if(pt)
{
clear(pt->_lchild);
clear(pt->_rchild);
delete(pt);
}
}
template <typename elemType>
inline ostream&
BinaryTree<elemType>::print(ostream& os) const
{
if( _root )
{
os << print( _root->_lchild );
os << _root->_val << ' ';
os << print( _root->_rchild );
}
return os;
} 人造人 发表于 2021-3-11 15:44
把所有的源代码都贴出来,说明哪一个代码在哪一个源文件,我在这边帮你看看
BTnode模板实例化出现了问题,问题应该就在BTnode.cpp当中,因为我尝试直接在BTnode.h上,在类内部定义,没有出现问题。 547658697 发表于 2021-3-11 15:57
BTnode模板实例化出现了问题,问题应该就在BTnode.cpp当中,因为我尝试直接在BTnode.h上,在类内部定义, ...
对,没错
模板的声明和定义不能分开,把 BTnode.cpp 的内容合并到 BTnode.h 就可以了
#ifndef BTNODE_H_INCLUDED
#define BTNODE_H_INCLUDED
template <typename Type>
class BinaryTree;
template <typename valType>
class BTnode
{
public:
friend class BinaryTree<valType>;
BTnode(const valType &val);
void insert_value( const valType &val);
void lchild_leaf(BTnode<valType> *leaf,BTnode<valType> *subtree );
void remove_value(valType &val , BTnode<valType> *prev);
private:
valType _val;
int _cnt;
BTnode* _lchild;
BTnode* _rchild;
};
template <typename valType>
inline BTnode<valType>::
BTnode(const valType &val):_val(val)
{
_cnt=1;
_lchild=_rchild=0;
}
template <typename valType>
inline void BTnode<valType>::
insert_value ( const valType &val )
{
if(_val == val )
_cnt++;
if(_val < val)
{
if(! _lchild)
_lchild = new BTnode<valType>(val);
else
_lchild->insert_value(val);
}
if(_val > val)
{
if(! _rchild)
_rchild = new BTnode<valType>(val);
else
_rchild->insert_value(val);
}
}
template <typename valType>
inline void BTnode<valType>::
lchild_leaf(BTnode<valType> *leaf,BTnode<valType> *subtree )
{
//找到没有左孩子的结点
while (! subtree->_lchild )
subtree = subtree->_lchild;
//找到了 subtree所指结点没有左子树
subtree->_lchild = leaf;
}
template <typename valType>
inline void BTnode<valType>::
remove_value(valType &val , BTnode<valType> *prev)
{
if (val < _val)
{
if( !_lchild )
return ;
else
{
_lchild->remove_value(val,_lchild);
}
}
else
if (val > _val)
{
if( !_rchild )
return ;
else
{
_rchild->remove_value(val,_rchild);
}
}
else
{
if(_rchild)
{
prev = _rchild;
if(_lchild)
{
if(!prev -> _lchild )
prev->_lchild =_lchild;
else
BTnode<valType>::lchild_leaf(_lchild,prev->_lchild);
}
}
else
prev = _lchild;
delete this;
}
}
#endif // BTNODE_H_INCLUDED
人造人 发表于 2021-3-11 16:08
对,没错
模板的声明和定义不能分开,把 BTnode.cpp 的内容合并到 BTnode.h 就可以了
非常感谢!问题解决了。
页:
[1]