16.4 类模板成员

Queue的实现:

1. 模板类定义

#include <iostream>
// 知识点:声明Queue模板类, 第三行的友类声明才成立
template<typename Type> class Queue; 
template<typename Type> std::ostream& operator<<(std::ostream&, Queue<Type>&); 
template<typename Type> class QueueItem {
	// 知识点: 限制其他类型的Queue<OtherType>访问 QueueItem
	friend class Queue<Type>; 
	friend std::ostream& operator<<<Type>(std::ostream&, Queue<Type>&); // 知识点:友元函数模板
	QueueItem(const Type& t) : item(t), next(0) {}
	Type item;
	QueueItem* next;
};

template<class Type> class Queue {
	friend std::ostream& operator<< <Type>(std::ostream&, Queue<Type>&);
public:
	Queue() : head(0), tail(0) {}
	Queue(const Queue&q):head(0),tail(0){ // 知识点: Queue(const Queue<Type>&) 
		copy_elems(q);
	}
	template<typename It>Queue(It start, It end): head(0),tail(0) {
		assign(start, end);
	}
	~Queue() { destroy(); }
	// 知识点:等效于 Queue<Type>& operator=(const Queue<Type>&);
	Queue& operator=(const Queue&); 
	Type& front() { return head->item; }
	const Type& front() const{  return head->item;  }
	void push(const Type&);
	void pop();
	template<typename It> void assign(It start, It end);
	bool empty() { return head == 0; }
private:
	QueueItem<Type>* head;
	QueueItem<Type>* tail;
	void destroy();
	void copy_elems(const Queue&);
};

2. 模板类内函数定义

template<class Type>  Queue<Type>& Queue<Type> ::operator=(const Queue& q) {
	destroy();
	copy_elems(q);
	return *this;
}
// 知识点 :operator << <Type> 
template<typename Type> std::ostream& operator<< <Type>(std::ostream& os, Queue<Type>& q) {
	QueueItem<Type>* ptr = q.head;
	os << "[";
	while (ptr) {
		os << ptr->item;
		ptr = ptr->next;
		if (ptr)
			os << ",";
	}
	os << "]";
	return os;
}
// 知识点:不恰当举例,为了说明模板类中的模板函数在类外的定义方式
template<typename type>template<typename It> void Queue<type>::assign(It start, It end) { 
	while (start != end)
		push(*start++);
}
template<class Type> void Queue<Type>::push(const Type& val) {
	QueueItem<Type> *pt = new QueueItem<Type>(val);
	if (empty())
		head = tail = pt;
	else {
		tail->next = pt;
		tail = pt;
	}
}
template<class Type> void Queue<Type>::pop() {
	QueueItem<Type> * p = head;
	head = head->next;
	delete p;
}
template<class Type> void Queue<Type>::copy_elems(const Queue&orig) {
	for (QueueItem<Type> *pt = orig.head; pt; pt = pt->next)
		push(pt->item);
}
template<class Type> void Queue<Type>::destroy() {
	while (!empty())
		pop();
}

注意点:

引用于:点击打开链接

1.在定义友元之前,我们对友元进行了声明。之前为一个类定义普通友元的时候,是无须声明的。这里必须对其声明的原因在于:我们定义的友元,也是模板。如果不声明,会是得友元函数和友元类的所有实例都能访问类的私有成员。当我们的QueueItem的内容是string型时,让Queue<int>类型也能访问是不合适的。

2. 由于类实例化时已经确定了成员函数的类型,所以这里不需要再进行模板实参推断了,这与普通函数模板不一样。当调用函数的实参与模板实例化后的形参不完全匹配时,可以会发生常规类型转换;不像函数模板,如果不匹配则出现错误。

举例:对于Queue<int> q,你仍然可以short sh = 4; q.push(sh);


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值