C++模板和继承
问题描述:
我遇到一些问题,使用模板和继承将代码分解为可重用部分。我想实现我的树类和avltree类使用相同的节点类,并且avltree类从树类继承了一些方法并添加了一些特定的方法。所以我想出了下面的代码。编译器会在下面标记的tree.h中引发一个错误,我不知道如何解决这个问题。任何帮助感谢! :)C++模板和继承
node.h:
#ifndef NODE_H
#define NODE_H
#include "tree.h"
template <class T>
class node
{
T data;
...
node()
...
friend class tree<T>;
};
#endif
tree.h中
#ifndef DREVO_H
#define DREVO_H
#include "node.h"
template <class T>
class tree
{
public: //signatures
tree();
...
void insert(const T&);
private:
node<T> *root; //missing type specifier - int assumed. Note: C++ does not support default-int
};
//implementations
#endif
avl.h
#ifndef AVL_H
#define AVL_H
#include "tree.h"
#include "node.h"
template <class T>
class avl: public tree<T>
{
public: //specific
int findMin() const;
...
protected:
void rotateLeft(node<T> *)const;
private:
node<T> *root;
};
#endif
avl.cpp(我试过实现分离头,它的工作在我开始将avl码与树码结合之前)
#include "drevo"
#include "avl.h"
#include "vozlisce.h"
template class avl<int>; //I know that only avl with int can be used like this, but currently this is doesn't matter :)
//implementations
...
答
tree.h
和node.h
都试图包括对方,包括警卫将阻止他们之一看到其他人。
而不是#include "tree.h"
尽量向前声明树,如:
template <class T>
class tree;
在node.h
编辑:作为SBI的评论所说,它更有意义转发声明tree
在node.h
比其他因为它是通过friend
声明授予tree
访问node
。
答
不要在“node.h”中包含“tree.h”。
此外,您在tree
和avl
类中都声明了root
。将tree::root
限定为protected
并删除avl::root
。
答
问题是因为tree.h和node.h之间的头文件的循环依赖。由于node.h包含tree.h,因此在编译树类时,编译器不知道节点的类型是什么。由于您只是为了宣告朋友而使用它,因此无需在node.h中包含头文件tree.h
答
您的问题是tree.h包含node.h,反之亦然。我不会认为节点必须知道树或给它友谊是必要的(或者说是有道理的),所以我会删除它。
我认为在''node.h“'中'#include”tree.h“'会比其他方式更有意义。毕竟,很难想象如何实现一个没有节点的树,而对于'friend'声明,'tree'的前向声明就足够了。 – sbi 2010-04-22 11:24:24
@sbi你当然是对的 – 2010-04-22 11:29:28
递归包括是如此有趣...你知道任何预处理器警告这些野兽吗?我的意思是可以写'#ifdef HEADER_GUARD \ n #error“HEADER_GUARD定义了”\ n#else'而不是'#ifndef',但它已经非常杂乱了...... – 2010-04-22 11:37:54