一个类模板程序:error LNK2019: 无法解析的外部符号 "class std::basic_ostream

没有昵称阿
阿里巴巴Java技术专家
博客专家认证
2012-02-18 09:08:02
本人现在正在看《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



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


在VS2008中运行出现以下错误:
1>------ 已启动生成: 项目: Queue, 配置: Debug Win32 ------
1>正在链接...
1>Queue.obj : error LNK2019: 无法解析的外部符号 "class std::basic_ostream<char,struct std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct std::char_traits<char> > &,class Queue<int> const &)" (??6@YAAAV?$basic_ostream@DU?$char_traits@D@std@@@std@@AAV01@ABV?$Queue@H@@@Z),该符号在函数 _main 中被引用
1>G:\程序练习\CPPPrimer\Queue\Debug\Queue.exe : fatal error LNK1120: 1 个无法解析的外部命令
1>生成日志保存在“file://g:\程序练习\CPPPrimer\Queue\Queue\Debug\BuildLog.htm”
1>Queue - 2 个错误,0 个警告
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========


请问这是问什么啊?求指导,感激不尽!
...全文
1895 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
程序员小迷 2012-02-20
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 xiajun07061225 的回复:]

引用 3 楼 cxsjabcabc 的回复:

引用 2 楼 xiajun07061225 的回复:

引用 1 楼 wangjunsheng 的回复:

template <class Type>
ostream&amp;amp;amp; operator<<(ostream &amp;amp;amp;os,const Queue<Type> &amp;a……
[/Quote]

楼主你写的啥友元啊,只是输出的友元,要看清楚啊。。。。
楼主写的友元是Queue类是QueueItem类的友元,
你的QueueItem自己的对象访问自己的private成员,。。。。上面的友元怎么能解决内部访问的问题?
楼主你看清楚啊。。

另外,我的代码gcc4.2编译运行通过的。。

楼主你到底有没有试过啊。。
bluewanderer 2012-02-20
  • 打赏
  • 举报
回复
#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;
}
没有昵称阿 2012-02-20
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 cxsjabcabc 的回复:]

引用 2 楼 xiajun07061225 的回复:

引用 1 楼 wangjunsheng 的回复:

template <class Type>
ostream&amp;amp; operator<<(ostream &amp;amp;os,const Queue<Type> &amp;amp;q)
{
os << "<";
QueueItem<Ty……
[/Quote]

都说了我已经声明友元了!!!!!!

照你那样改成publi还是出现同样的错误,所以肯定不是这儿的问题。

难道是编译器配置的问题?

求指导!
没有昵称阿 2012-02-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 cxsjabcabc 的回复:]

引用 4 楼 xiajun07061225 的回复:

引用 3 楼 cxsjabcabc 的回复:

引用 2 楼 xiajun07061225 的回复:

引用 1 楼 wangjunsheng 的回复:

template <class Type>
ostream&amp;amp;amp;amp; operator<<(ostream &amp;amp;a……
[/Quote]

在此感谢你~~我已经明白了~~~~呵呵~~

结贴给分!!!
没有昵称阿 2012-02-20
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 cxsjabcabc 的回复:]

引用 4 楼 xiajun07061225 的回复:

引用 3 楼 cxsjabcabc 的回复:

引用 2 楼 xiajun07061225 的回复:

引用 1 楼 wangjunsheng 的回复:

template <class Type>
ostream&amp;amp;amp;amp; operator<<(ostream &amp;amp;a……
[/Quote]
我用VS2008试过了的~~

谢谢你的建议,我再思考一下!
程序员小迷 2012-02-19
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 xiajun07061225 的回复:]

引用 1 楼 wangjunsheng 的回复:

template <class Type>
ostream&amp; operator<<(ostream &amp;os,const Queue<Type> &amp;q)
{
os << "<";
QueueItem<Type> *p;
for (p = q .front;p;p = p ->next)……
[/Quote]

楼主把代码改为这样即可:



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

template <class T>
friend ostream& operator<<(ostream&,const QueueItem<Type>&);
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 T>
ostream& operator<<(ostream &os,const Queue<T> &q)
{
os << "<";
QueueItem<T> *p;
for (p = q.front;p;p = p->next)
{
os << *p << " ";
}
os << ">";

return os;
}

template <class T>
ostream& operator<<(ostream &os,const QueueItem<T> &qi)
{
os << qi.item;
return os;
}



int main()
{
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;
}



p->next这个p需要访问它的next,所以next得是public的
没有昵称阿 2012-02-18
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 wangjunsheng 的回复:]

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 <<……
[/Quote]

我已经声明了友元啊?这应该不是访问next的问题呀~~
乃不知有汉 2012-02-18
  • 打赏
  • 举报
回复
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;
}
cannot access private member declared in class 'QueueItem<int>'

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: // 这里改为 public 或 提供方法 访问next
Type item;
QueueItem *next;
};

64,676

社区成员

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

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