64,690
社区成员
发帖
与我相关
我的任务
分享
// Queue.h
#ifndef QUEUE_H
#define QUEUE_H
#include <iostream>
using std::ostream ;
using std::istream ;
// function template declaration must precede
// friend declaration in QueueItem
template <class T> class Queue;
template <class T>
ostream& operator<<(ostream&, const Queue<T>&);
template <class T>
istream& operator>>(istream&, Queue<T>&);
template <class Type> class QueueItem {
friend class Queue<Type>;
// needs access to item and next
friend ostream& operator<< <Type> (ostream&, const Queue<Type>&);
// private class: no public section
QueueItem(const Type &t): item(t), next(0) { }
//~QueueItem() { delete next; } //书上没有这句,不知道加了这句对不对。
Type item; // value stored in this element
QueueItem *next; // pointer to next element in the Queue
};
template <class Type> class Queue {
public:
// needs access to head
friend ostream&
operator<< <Type> (ostream&, const Queue<Type>&);
friend istream&
operator>> <Type> (istream&, Queue<Type>&);
// empty Queue
Queue(): head(0), tail(0) { }
// copy control to manage pointers to QueueItems in the Queue
Queue(const Queue &Q): head(0), tail(0)
// 和这条语句是等价的:Queue<Type>(const Queue &Q): head(0), tail(0)
{ copy_elems(Q); }
Queue& operator=(const Queue&);
~Queue() { destroy(); }
// return element from head of Queue
// unchecked operation: front on an empty Queue is undefined
Type& front() { return head->item; }
const Type &front() const { return head->item; }
void push(const Type &); // add element to back of Queue
void pop (); // remove element from head of Queue
bool empty () const { // true if no elements in the Queue
return head == 0;
}
private:
QueueItem<Type> *head; // pointer to first element in Queue
QueueItem<Type> *tail; // pointer to last element in Queue
// utility functions used by copy constructor, assignment, and destructor
void destroy(); // delete all the elements
void copy_elems(const Queue&); // copy elements from parameter
};
#endif
/////////////////////////////////////////////////////////////
// Queue.cpp
#include "Queue.h"
template <class Type> void Queue<Type>::destroy() {
while (!empty())
pop();
}
template <class Type> void Queue<Type>::pop()
{
// pop is unchecked: Popping off an empty Queue is undefined
QueueItem<Type>* p = head; // keep pointer to head so we can delete it
head = head->next; // head now points to next element
delete p; // delete old head element
}
template <class Type> void Queue<Type>::push(const Type &val)
{
// allocate a new QueueItem object
QueueItem<Type> *pt = new QueueItem<Type>(val);
// put item onto existing queue
if (empty())
head = tail = pt; // the queue now has only one element
else {
tail->next = pt; // add new element to end of the queue
tail = pt;
}
}
template <class Type>
void Queue<Type>::copy_elems(const Queue &orig)
{
// copy elements from orig into this Queue
// loop stops when pt == 0, which happens when we reach orig.tail
for (QueueItem<Type> *pt = orig.head; pt; pt = pt->next)
push(pt->item); // copy the element
}
template <class Type>
Queue<Type>& Queue<Type>::operator=(const Queue& q) {
if(*this != q) {
head = q.head;
tail = q.tail;
}
return *this;
}
template <class Type>
ostream& operator<<(ostream &os, const Queue<Type> &q)
{
os << "< ";
QueueItem<Type> *p;
for (p = q.head; p; p = p->next)
os << p->item << " ";
os <<">";
return os;
}
template <class Type>
istream& operator>>(ostream &is, const Queue<Type> &q)
{
Type val;
while(is>>val)
q.push(val);
return is;
}
///////////////////////////////////////////
// Queue_main.cpp
#include "Queue.h"
#include <iostream>
int main()
{
Queue<int> q;
// 将Queue<Tpye>::destroy()及Queue<Type>::pop的定义放在头文件中则没
// 有这个链接错误。放在这儿就不行了:
// Queue_main.obj : error LNK2019:
// 无法解析的外部符号 "private: void __thiscall Queue<int>::destroy(void)"
// (?destroy@?$Queue@H@@AAEXXZ),
// 该符号在函数 "public: __thiscall Queue<int>::~Queue<int>(void)"
// (??1?$Queue@H@@QAE@XZ) 中被引用
std::cin >> q;
// 将operator>><Type>的定义放在头文件中也不能消除这个链接错误。
// Queue_main.obj : error LNK2019:
// 无法解析的外部符号 "class std::basic_istream<char,
// struct std::char_traits<char> > & __cdecl operator>><int>
// (class std::basic_istream<char,struct std::char_traits<char> > &,
// class Queue<int> &)" (??$?5H@@YAAAV?$basic_istream@DU?$
// char_traits@D@std@@@std@@AAV01@AAV?$Queue@H@@@Z),
// 该符号在函数 _main 中被引用
std::cout << q << std::endl;
// 将operator<<<Type>的定义放在头文件中则没有这个链接错误。放在这儿就不行了:
// Queue_main.obj : error LNK2019:
// 无法解析的外部符号 "class std::basic_ostream<char,
// struct std::char_traits<char> > & __cdecl operator<<<int>
// (class std::basic_ostream<char,struct std::char_traits<char> > &,
// class Queue<int> const &)" (??$?6H@@YAAAV?$basic_ostream@DU?$
// char_traits@D@std@@@std@@AAV01@ABV?$Queue@H@@@Z),
// 该符号在函数 _main 中被引用
return 0;
}
template <class Type>
istream& operator>>(istream &is, Queue<Type> &q)
{
Type val;
while(is>>val)
q.push(val);
return is;
}
我自认为还是一个比较细心的人,没想到在这两个小问题上竟然把自己闹腾了这么久!!
现在贴子陈述的问题基本算是解决了,谢谢你们!
我又把代码移动了一下,发现有的成员函数可以放在cpp文件中,比如:
template <class Type> void Queue<Type>::copy_elems(const Queue &orig){ //... }
template <class Type> Queue<Type>& Queue<Type>::operator=(const Queue& q) { //... }
但有的却不行,比如:
template <class Type> void Queue<Type>::push(const Type &val) { //... }
template <class Type> void Queue<Type>::pop() { //... }
template <class Type> void Queue<Type>::destroy() { //... }
一时还没搞清楚是为什么。不过这已经超出本贴子的内容了,再次向你们表示感谢!