2012-02-18 72 views
0

我刚开始学习C++,现在正在使用类模板编写一个C++程序。它实现了一些简单的队列函数。但是出现错误。 该程序得出两个文件:Queue.h和Queue.cpp.Now我张贴我的代码。 Queue.h:使用类模板的C++程序:错误LNK2019

#ifndef QUEUE_H 
#define QUEUE_H 

#include <iostream> 
#include <cstdlib> 
using namespace std; 

template <class T> class QueueItem; 

//define class template 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; 
}; 

//define class template 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 

Queue.cpp:

#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; 
} 

但我在Visual Studio 2008中得到一个错误: 1> Queue.obj:错误LNK2019:无法解析的外部符号“类性病: :basic_ostream> & __cdecl运算符< <(class std :: basic_ostream> &,class Queue const &)“(?? 6 @ YAAAV?$ basic_ostream @ DU?$ char_traits @ D @ std @@@ std @@ AAV01 @ ABV ?$ Queue @ H @@@ Z),该符号在函数_main中被引用1> G:\ CPPPrimer \ Queue \ Debug \ Queue.exe:致命错误LNK1120:无法解析的外部符号

有谁能告诉我为什么? 非常感谢。

我已经解决了我的problems.This是我的代码,在Visual Studio 2008中正常运行:

#include <iostream> 
#include <cstdlib> 
using namespace std; 

template <class Type> 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 T> 
    friend ostream& operator<<(ostream&,const Queue<T> &); 

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>; 

    //将输出符号声明为函数模板 
    template <class T> 
    friend ostream& operator<<(ostream&,const QueueItem<T>&); 

private: 
    Type item; 
public: 
    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; 
} 

int main() 
{ 
    //Queue<int> *p_qi = new Queue<int>; 
    //ostream& operator<<(ostream &os,const Queue<int>&); 
    //ostream& operator<<(ostream &os,const QueueItem<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; 
} 
+0

字面上有一百万重复的这一个SO ... – 2012-02-18 01:40:40

+0

可能重复[C++ - LNK2019错误无法解析的外部符号\ [模板类的构造函数和析构函数\]引用函数_main](http://stackoverflow.com/问题/ 3705740/c-lnk2019-error-unresolved-external-symbol-template-classs-constructor-and) – ruakh 2012-02-18 01:45:02

回答

1

您需要首先声明你的运营商,因为这样的:

template <typename Type> class Queue; 
template <typename Type> class QueueItem; 

template <typename Type> 
ostream& operator<<(ostream &os,const Queue<Type> &q); 

template <typename Type> 
ostream& operator<<(ostream &os,const QueueItem<Type> &qi); 

而且朋友声明需要模板参数:

friend ostream& operator<< <Type>(ostream&,const Queue<Type> &); 
friend ostream& operator<< <Type>(ostream&,const QueueItem<Type> &); 

此编译,链接和运行下gcc和铛。顺便说一句,QueueItem需要有两个操作员作为朋友,因为打印队列的代码也使用QueueItem成员。就个人而言,我会建议实施const访问器并摆脱朋友altogther。

+0

非常感谢。我已经解决了这个问题。输出符号“<<”应该声明为函数模板。并且类QueueItem成员“next”应该声明为public.This我的代码正确运行在Visual Studio 2008上。 – XiaJun 2012-02-20 11:05:24