关于模板和友元的简单问题,在线等
VC++中类模板的声明和其中的函数定义必须放在同一个头文件中.
现在有两个类模板,我都把它们放在一个头文件中,并声明其中的一个类是另一个类的友元. 但是编译没有通过,程序如下, 还请各位指点,问题解决就给分.
#include <iostream.h>
#include "OutOfBounds.h"
template <class T>
class Chain<T>; // 前向引用不知写法是否正确????
template <class T>
class ChainNode {
friend Chain<T>;
private:
T data;
ChainNode<T> *link;
};
template<class T>
class Chain {
public:
Chain() {first = 0;}
~Chain();
bool isEmpty() const {return first == 0;}
int length() const;
bool find(int k, T& x) const;
int search(const T& x) const;
Chain<T>& del(int k, T& x);
Chain<T>& insert(int k, const T& x);
void output(ostream& out) const;
private:
ChainNode<T> *first; // 指向第一个节点的指针
};
template<class T>
Chain<T>::~Chain(){ // 链表的析构函数,用于删除链表中的所有节点
ChainNode<T> *next; // 下一个节点
while (first) {
next = first->link;
delete first;
first = next;
}
}
template<class T>
int Chain<T>::length() const { // 返回链表中的元素总数
ChainNode<T> *current = first;
int len = 0;
while (current) {
len++;
current = current->link;
}
return len;
}
template<class T>
bool Chain<T>::find(int k, T& x) const { // 寻找链表中的第k 个元素,并将其传送至x
//如果不存在第k 个元素,则返回false,否则返回true
if (k < 1) return false;
ChainNode<T> *current = first;
int index = 1; // current 的索引
while (index < k && current) {
current = current->link;
index++;
}
if (current) {x = current->data; return true;}
return false; // 不存在第k 个元素
}
template<class T>
int Chain<T>::search(const T& x) const{
// 寻找x ,如果发现x ,则返回x 的地址
// 如果x 不在链表中,则返回0
ChainNode<T> *current = first;
int index = 1; // current 的索引
while (current && current->data != x) {
current = current->link;
index++;
}
if (current) return index;
return 0;
}
template<class T>
void Chain<T>::output(ostream& out) const{
// 将链表元素送至输出流
ChainNode<T> *current;
for (current = first; current; current = current->link)
out << current->data << " ";
}
template <class T>
ostream& operator<<(ostream& out, const Chain<T>& x)
{x.output(out); return out;}
template<class T>
Chain<T>& Chain<T>::del(int k, T& x){
// 把第k 个元素取至x ,然后从链表中删除第k 个元素
// 如果不存在第k 个元素,则引发异常OutOfBounds
if (k < 1 || !first)
throw OutOfBounds(); // 不存在第k 个元素
// p 最终将指向第k 个节点
ChainNode<T> *p = first;
// 将p 移动至第k 个元素,并从链表中删除该元素
if (k == 1) // p 已经指向第k 个元素
first = first->link; // 删除之
else { // 用q 指向第k - 1 个元素
ChainNode<T> *q = first;
for (int index = 1; index < k - 1 && q; index++)
q = q->link;
if (!q || !q->link)
throw OutOfBounds(); //不存在第k 个元素
p = q->link; // 存在第k 个元素
q->link = p->link;
} // 从链表中删除该元素
//保存第k 个元素并释放节点p
x = p->data;
delete p;
return *this;
}
template<class T>
Chain<T>& Chain<T>::insert(int k, const T& x){
// 在第k 个元素之后插入x
// 如果不存在第k 个元素,则引发异常OutOfBounds
// 如果没有足够的空间,则传递NoMem异常
if (k < 0) throw OutOfBounds();
// p 最终将指向第k 个节点
ChainNode<T> *p = first;
// 将p 移动至第k 个元素
for (int index = 1; index < k && p; index++)
p = p->getLink();
if (k > 0 && !p) throw OutOfBounds(); //不存在第k 个元素
// 插入
ChainNode<T> *y=new ChainNode<T>;
y->getData() = x;
if (k) { // 在p 之后插入
y->getLink() = p->getLink();
p->getLink() = y;
}
else { // 作为第一个元素插入
y->getLink() = first;
first = y;
}
return *this;
}