初学模板编程,在实现Queue类时遇到了困难,求救!

Really_want 2012-12-05 06:43:16
我只能算是一个C++初学者。白天上课,只能晚上有空才学习一下。
以前遇到的问题在CSDN上一搜基本都能解决,这次不行了,
我已经连续两个晚上没睡好了。希望有高人指点指点。。。
我用的是vs2010:

// 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;
}
...全文
161 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
Really_want 2012-12-05
  • 打赏
  • 举报
回复
引用 4 楼 supermegaboy 的回复:
引用 3 楼 akirya 的回复:istream&amp; operator>>(ostream &amp;is, const Queue<Type> &amp;q) 多了个const 还有ostream也应改为istream
你们俩都很细心地帮我看了,非常感谢!我已经改成这样了,并且把模板定义都放到了头文件中,然后链接成功了!
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() { //... } 一时还没搞清楚是为什么。不过这已经超出本贴子的内容了,再次向你们表示感谢!
飞天御剑流 2012-12-05
  • 打赏
  • 举报
回复
引用 3 楼 akirya 的回复:
istream& operator>>(ostream &is, const Queue<Type> &q) 多了个const
还有ostream也应改为istream
  • 打赏
  • 举报
回复
istream& operator>>(ostream &is, const Queue<Type> &q) 多了个const
Really_want 2012-12-05
  • 打赏
  • 举报
回复
我试了,这样可以消除‘<<’和析构函数造成的链接错误。也就是“Queue<int> q;”和“std::cout << q << std::endl;”没问题了。但‘>>’还是不能用。
  • 打赏
  • 举报
回复
将模板实现都放到头文件中

64,690

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧