一个类模板程序:error LNK2019: 无法解析的外部符号 "class std::basic_ostream
本人现在正在看《C++ Primer(第三版)》的类模板一章,在实现书中的代码时,出现了这样的错误。
下面是一个简单的利用了类模板的实现队列简单操作的代码,总共包括两个文件(Queue.h和Queue.cpp):
Queue.h:
#ifndef QUEUE_H#define QUEUE_H#include <iostream>#include <cstdlib>using namespace std;template <class T> class QueueItem;//类模板Queue的定义template <class Type>class Queue{public: Queue():front(0),back(0){} ~Queue(); Type remove(); void add(const Type&); bool is_empty() const{ return front == 0; } friend ostream& operator<<(ostream&,const Queue<Type> &);private: QueueItem<Type> *front; QueueItem<Type> *back;};//类模板QueueItem的定义template <class Type> class QueueItem{public: QueueItem(const Type&t):item(t),next(0){} friend class Queue<Type>; friend ostream& operator<<(ostream&,const QueueItem<Type>&);private: Type item; QueueItem *next;};template <class Type>Queue<Type>::~Queue(){ while(!is_empty()) remove();}template <class Type>void Queue<Type>::add(const Type &val){ QueueItem<Type> *pt = new QueueItem<Type>(val); if (is_empty()) front = back = pt; else { back ->next = pt; back = pt; }}template <class Type>Type Queue<Type>::remove(){ if (is_empty()) { cerr << "remove() on empty queue!"<<endl; exit(-1); } QueueItem<Type> *pt = front; front = front ->next; Type retval = pt ->item; delete pt; return retval;}template <class Type>ostream& operator<<(ostream &os,const Queue<Type> &q){ os << "<"; QueueItem<Type> *p; for (p = q .front;p;p = p ->next) { os << *p << " "; } os << ">"; return os;}template <class Type>ostream& operator<<(ostream &os,const QueueItem<Type> &qi){ os << qi.item; return os;}#endif#include "Queue.h"#include <iostream>using namespace std;int main(){ //Queue<int> *p_qi = new Queue<int>; Queue<int> p_qi; cout << p_qi <<endl; for (int ival = 0;ival < 10;++ival) { p_qi .add(ival); } cout << p_qi <<endl; int err_cnt = 0; for (int ival = 0;ival < 10;++ival) { int qval = p_qi .remove(); if (qval != ival) ++err_cnt; } cout << p_qi <<endl; if (!err_cnt) cout << "!!Queue executed OK!"<<endl; else cout << "??Queue errors:"<<err_cnt << endl; return 0;}
#include <iostream>#include <cstdlib>using namespace std;template <class T> class QueueItem;//类模板Queue的定义template <class Type>class Queue{public: Queue():front(0),back(0){} ~Queue(); Type remove(); void add(const Type&); bool is_empty() const{ return front == 0; } // 不这么写函数实现的模板不会实例化 template <class Type> friend ostream& operator<<(ostream&,const Queue<Type> &); //或者写 效果一样 下同 //friend ostream& operator<<<>(ostream&,const Queue<Type> &);private: QueueItem<Type> *front; QueueItem<Type> *back;};//类模板QueueItem的定义template <class Type> class QueueItem{public: QueueItem(const Type&t):item(t),next(0){} friend class Queue<Type>; // 少了一个friend template <class Type> friend ostream& operator<<(ostream&,const Queue<Type> &); template <class Type> friend ostream& operator<<(ostream&,const QueueItem<Type>&);private: Type item; QueueItem *next;};template <class Type>Queue<Type>::~Queue(){ while(!is_empty()) remove();}template <class Type>void Queue<Type>::add(const Type &val){ QueueItem<Type> *pt = new QueueItem<Type>(val); if (is_empty()) front = back = pt; else { back ->next = pt; back = pt; }}template <class Type>Type Queue<Type>::remove(){ if (is_empty()) { cerr << "remove() on empty queue!"<<endl; exit(-1); } QueueItem<Type> *pt = front; front = front ->next; Type retval = pt ->item; delete pt; return retval;}template <class Type>ostream& operator<<(ostream &os,const Queue<Type> &q){ os << "<"; QueueItem<Type> *p; for (p = q .front;p;p = p ->next) { os << *p << " "; } os << ">"; return os;}template <class Type>ostream& operator<<(ostream &os,const QueueItem<Type> &qi){ os << qi.item; return os;}#include <iostream>using namespace std;int main(){ //Queue<int> *p_qi = new Queue<int>; Queue<int> p_qi; cout << p_qi <<endl; for (int ival = 0;ival < 10;++ival) { p_qi .add(ival); } cout << p_qi <<endl; int err_cnt = 0; for (int ival = 0;ival < 10;++ival) { int qval = p_qi .remove(); if (qval != ival) ++err_cnt; } cout << p_qi <<endl; if (!err_cnt) cout << "!!Queue executed OK!"<<endl; else cout << "??Queue errors:"<<err_cnt << endl; return 0;}
[解决办法]