一个友元函数的问题

happyjessica2008 2010-06-12 01:44:39
我建立的类List是一个列表类,程序中我用了类模板,类的定义如下:
template<class T>
class List
{
public:
List(int max);
~List();
int length() const;
void add(T new_item);
bool full() const;
void erase();
friend ostream& operator <<(ostream& outs,const List<T>& the_list);
private:
T *item; //列表的首地址
int max_length;
int current_length;
};

我把重载的<<运算符的函数设置为List类的友元,具体代码如下:
template<class T>
ostream& operator <<(ostream& outs,const List<T>& the_list)
{ //重载<<运算符,用<<运算符输出列表各元素的值
for(int i=0;i<the_list.current_length;i++)
{
outs<<the_list.item[i]<<endl;
}
return outs;
}

可是程序运行总是有4个错误,错误指向上面的代码,大概是说重载运算符函数不能调用私有成员,错误内容如下:

list.cpp
f:\c++程序设计\c++面向对象程序设计\14_4\list.h(25) : error C2248: 'current_length' : cannot access private member declared in class 'List<int>'
f:\c++程序设计\c++面向对象程序设计\14_4\list.h(19) : see declaration of 'current_length'
F:\C++程序设计\C++面向对象程序设计\14_4\list.cpp(8) : see reference to function template instantiation 'class std::basic_ostream<char,struct std::char_traits<char> > &__cdecl operator <<(class std::basic_ostream<char,struct std::char_traits<
char> > &,const class List<int> &)' being compiled
f:\c++程序设计\c++面向对象程序设计\14_4\list.h(27) : error C2248: 'item' : cannot access private member declared in class 'List<int>'
f:\c++程序设计\c++面向对象程序设计\14_4\list.h(17) : see declaration of 'item'
F:\C++程序设计\C++面向对象程序设计\14_4\list.cpp(8) : see reference to function template instantiation 'class std::basic_ostream<char,struct std::char_traits<char> > &__cdecl operator <<(class std::basic_ostream<char,struct std::char_traits<
char> > &,const class List<int> &)' being compiled
f:\c++程序设计\c++面向对象程序设计\14_4\list.h(25) : error C2248: 'current_length' : cannot access private member declared in class 'List<char>'
f:\c++程序设计\c++面向对象程序设计\14_4\list.h(19) : see declaration of 'current_length'
F:\C++程序设计\C++面向对象程序设计\14_4\list.cpp(14) : see reference to function template instantiation 'class std::basic_ostream<char,struct std::char_traits<char> > &__cdecl operator <<(class std::basic_ostream<char,struct std::char_traits
<char> > &,const class List<char> &)' being compiled
f:\c++程序设计\c++面向对象程序设计\14_4\list.h(27) : error C2248: 'item' : cannot access private member declared in class 'List<char>'
f:\c++程序设计\c++面向对象程序设计\14_4\list.h(17) : see declaration of 'item'
F:\C++程序设计\C++面向对象程序设计\14_4\list.cpp(14) : see reference to function template instantiation 'class std::basic_ostream<char,struct std::char_traits<char> > &__cdecl operator <<(class std::basic_ostream<char,struct std::char_traits
<char> > &,const class List<char> &)' being compiled
Error executing cl.exe.

list.obj - 4 error(s), 0 warning(s)

我感觉好像我设置的友元没起作用似的,请问为什么?我是新手,请尽可能详细的回答,多谢了。
完整的代码如下:


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

template<class T>
class List
{
public:
List(int max);
~List();
int length() const;
void add(T new_item);
bool full() const;
void erase();
friend ostream& operator <<(ostream& outs,const List<T>& the_list);
private:
T *item; //列表的首地址
int max_length;
int current_length;
};

template<class T>
ostream& operator <<(ostream& outs,const List<T>& the_list)
{ //重载<<运算符,用<<运算符输出列表各元素的值
for(int i=0;i<the_list.current_length;i++)
{
outs<<the_list.item[i]<<endl;
}
return outs;
}

template<class T>
List<T>::List(int max):max_length(max),current_length(0)
{
item=new T[max];
}

template<class T>
List<T>::~List()
{
delete [] item;
}

template<class T>
int List<T>::length() const
{
return current_length;
}

template<class T>
void List<T>::add(T new_item)
{
if(full())
{
cout<<"error:adding to a full list.";
exit(1);
}
else
{
item[current_length]=new_item;
current_length=current_length+1;
}
}

template<class T>
bool List<T>::full() const
{
return current_length==max_length;
}

template<class T>
void List<T>::erase()
{
current_length=0;
}

//主函数体内容如下:
#include "list.h"
void main()
{
List<int> first_list(2);
first_list.add(1);
first_list.add(2);
cout<<"first list = \n"<<first_list;

List<char> second_list(10);
second_list.add('A');
second_list.add('B');
second_list.add('C');
cout<<"second list = \n"<<second_list;

}

...全文
478 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
Simao 2010-06-12
  • 打赏
  • 举报
回复
vc6 真的这么差吗???
liutengfeigo 2010-06-12
  • 打赏
  • 举报
回复

lthyxy: VC6 对C++标准支持得不好,听taodm的吧,远离它
happyjessica2008 2010-06-12
  • 打赏
  • 举报
回复
这是什么答案呀,不过还是谢谢pengzhixi帮我解决问题,结贴!!!!!!!!!!
pengzhixi 2010-06-12
  • 打赏
  • 举报
回复
答案见LS
taodm 2010-06-12
  • 打赏
  • 举报
回复
答案见1楼
happyjessica2008 2010-06-12
  • 打赏
  • 举报
回复
to:pengzhixi

按你说的做真的可以了,可以给我解释一下为什么吗?按理说把重载函数体放在类里面和放在类外面应该没有什么区别呀?
pengzhixi 2010-06-12
  • 打赏
  • 举报
回复
如果是vc6.0那么就这样了。
template<class T>
class List
{
public:
List(int max);
~List();
int length() const;
void add(T new_item);
bool full() const;
friend ostream& operator <<(ostream& outs,const List<T> & the_list){for(int i=0; i<the_list.current_length; i++)
{
outs<<the_list.item[i]<<endl;
}
return outs;
}
void erase();
private:
T *item; //列表的首地址
int max_length;
int current_length;
};

后面那个模板就不要了。

happyjessica2008 2010-06-12
  • 打赏
  • 举报
回复
to:pengzhixi
我用vc++好像不行呀,改成下面这样还是刚才那两个错误。

template<class T>
class List
{
public:
List(int max);
~List();
int length() const;
void add(T new_item);
bool full() const;
template<class M> friend ostream& operator <<(ostream& outs,const List<M> & the_list);
void erase();
private:
T *item; //列表的首地址
int max_length;
int current_length;
};

template<class M>
ostream& operator <<(ostream& outs,const List<M> & the_list)
{
//重载<<运算符,用<<运算符输出列表各元素的值
for(int i=0; i<the_list.current_length; i++)
{
outs<<the_list.item[i]<<endl;
}
return outs;
}
pengzhixi 2010-06-12
  • 打赏
  • 举报
回复
我在DEV-CPP下编译的话,只要将template<class T> friend ostream里面的模板参数T不和List的模板参数T同名就没有任何问题。
happyjessica2008 2010-06-12
  • 打赏
  • 举报
回复
谢谢pengzhixi,代码如下:


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

template<class T>
class List
{
public:
List(int max);
~List();
int length() const;
void add(T new_item);
bool full() const;
template<class T> friend ostream& operator <<(ostream& outs,const List<T> & the_list);
void erase();
private:
T *item; //列表的首地址
int max_length;
int current_length;
};

template<class T>
ostream& operator <<(ostream& outs,const List<T> & the_list)
{
//重载<<运算符,用<<运算符输出列表各元素的值
for(int i=0; i<the_list.current_length; i++)
{
outs<<the_list.item[i]<<endl;
}
return outs;
}

template<class T>
List<T>::List(int max):max_length(max),current_length(0)
{
item=new T[max];
}

template<class T>
List<T>::~List()
{
delete [] item;
}

template<class T>
int List<T>::length() const
{
return current_length;
}

template<class T>
void List<T>::add(T new_item)
{
if(full())
{
cout<<"error:adding to a full list.";
exit(1);
}
else
{
item[current_length]=new_item;
current_length=current_length+1;
}
}

template<class T>
bool List<T>::full() const
{
return current_length==max_length;
}

template<class T>
void List<T>::erase()
{
current_length=0;
}


//主函数体内容如下:
#include "list.h"
int main()
{
List<int> first_list(2);
first_list.add(1);
first_list.add(2);
cout<<"first list = \n"<<first_list;

List<char> second_list(10);
second_list.add('A');
second_list.add('B');
second_list.add('C');
cout<<"second list = \n"<<second_list;
return 0;
}
pengzhixi 2010-06-12
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 happyjessica2008 的回复:]
to:jsjrj01,pengzhixi

你们的意思是在声明友元函数的时候前面加上template<class T>
我试过了,原来的错误没了,但又有两个新错误如下:
c:\documents and settings\administrator\桌面\新建文件夹 (2)\sdfd\list.h(30) : error C2562: '<<' : 'void' function retu……
[/Quote]
请把你改过后的代码发上来
happyjessica2008 2010-06-12
  • 打赏
  • 举报
回复
to:jsjrj01,pengzhixi

你们的意思是在声明友元函数的时候前面加上template<class T>
我试过了,原来的错误没了,但又有两个新错误如下:
c:\documents and settings\administrator\桌面\新建文件夹 (2)\sdfd\list.h(30) : error C2562: '<<' : 'void' function returning a value
c:\documents and settings\administrator\桌面\新建文件夹 (2)\sdfd\list.h(14) : see declaration of '<<'
c:\documents and settings\administrator\桌面\新建文件夹 (2)\sdfd\list.cpp(8) : see reference to function template instantiation 'void __cdecl operator <<(class std::basic_ostream<char,struct std::char_traits<char> > &,const class List<int> &
)' being compiled
c:\documents and settings\administrator\桌面\新建文件夹 (2)\sdfd\list.h(30) : error C2562: '<<' : 'void' function returning a value
c:\documents and settings\administrator\桌面\新建文件夹 (2)\sdfd\list.h(14) : see declaration of '<<'
c:\documents and settings\administrator\桌面\新建文件夹 (2)\sdfd\list.cpp(14) : see reference to function template instantiation 'void __cdecl operator <<(class std::basic_ostream<char,struct std::char_traits<char> > &,const class List<char>
&)' being compiled
Error executing cl.exe.

还请大家再帮我想想办法
wanilyer 2010-06-12
  • 打赏
  • 举报
回复
把友元函数的定义改成下面这样

friend ostream& operator<< <T>(ostream& outs,const List<T>& the_list);
别逗我乐 2010-06-12
  • 打赏
  • 举报
回复
#include <iostream>
#include <cstdlib>
using namespace std;

template<class T>
class List
{
public:
List(int max);
~List();
int length() const;
void add(T new_item);
bool full() const;
template<class M>
friend ostream& operator <<(ostream& outs,const List<M> & the_list);
void erase();
private:
T *item; //列表的首地址
int max_length;
int current_length;
};

template<class M>
ostream& operator <<(ostream& outs,const List<M> & the_list)
{
//重载<<运算符,用<<运算符输出列表各元素的值
for(int i=0; i<the_list.current_length; i++)
{
outs<<the_list.item[i]<<endl;
}
return outs;
}

template<class T>
List<T>::List(int max):max_length(max),current_length(0)
{
item=new T[max];
}

template<class T>
List<T>::~List()
{
delete [] item;
}

template<class T>
int List<T>::length() const
{
return current_length;
}

template<class T>
void List<T>::add(T new_item)
{
if(full())
{
cout<<"error:adding to a full list.";
exit(1);
}
else
{
item[current_length]=new_item;
current_length=current_length+1;
}
}

template<class T>
bool List<T>::full() const
{
return current_length==max_length;
}

template<class T>
void List<T>::erase()
{
current_length=0;
}

//主函数体内容如下:
#include "list.h"
int main()
{
List<int> first_list(2);
first_list.add(1);
first_list.add(2);
cout<<"first list = \n"<<first_list;

List<char> second_list(10);
second_list.add('A');
second_list.add('B');
second_list.add('C');
cout<<"second list = \n"<<second_list;
return 0;
}


/*
first list =
1
2
second list =
A
B
C

Process returned 0 (0x0) execution time : 0.016 s
Press any key to continue.
*/
z569362161 2010-06-12
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 taodm 的回复:]
珍惜生命,远离VC6
[/Quote]

真的不要用V6了,2010都出来了。
pengzhixi 2010-06-12
  • 打赏
  • 举报
回复
template<class T>
class List
{
public:
List(int max);
~List();
int length() const;
void add(T new_item);
bool full() const;
void erase();
template<class M>friend ostream& operator <<(ostream& outs,const List<m>& the_list);
private:
T *item; //列表的首地址
int max_length;
int current_length;
};
taodm 2010-06-12
  • 打赏
  • 举报
回复
珍惜生命,远离VC6

64,656

社区成员

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

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