关于友元在类外定义还是在类内定义的问题

crabscale 2006-12-25 09:44:54
昨天看到论坛里一篇关于重载operator <<的帖子,我试了下,有一个问题不明白,以前倒没注意过,代码如下请各位看一下:
#include <iostream>
#include <string>
using namespace std;
class student
{
public:
int key;
string name;
friend ostream & operator << (ostream &s,const student &k)
{
cout << "in";
return s;
}
friend void ff(student &s)
{
cout<<s.name<<endl;
};
student(){};
virtual ~student(){};
student(string &s);

};

student::student(string &s)
{
name=s;
}

ostream & operator << (ostream &s,const student &k)
{
cout<<"out";
//printf("name=%s,key=%d\n", k.name, k.key);
//printf("name=%s,key=%d\n", "k.name", 1);
return s;
}

void ff(student &s)
{
cout<<"out"<<endl;
}

void main()
{
string t="tim";
const student s1(t);
cout<<s1<<endl;
}

出现两个错误,一个是说函数ff已经有定义了,另一个是说operator<< is ambiguous,两个函数都是友元函数,怎么会有上面两个不同的错误? 我把类外面的operator<<参数去掉const就会少一个错误了,这应该是函数解析对了,但为什么函数ff没有出现类似的问题呢?而是说已经定义过了呢?是不是友元函数实现应该放在类定义之内?
...全文
460 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
lann64 2006-12-25
  • 打赏
  • 举报
回复
是呀,别用vc6啊。
前面不是说了,vc6对友元函数支持不好。用其他的编译器。
v2002750 2006-12-25
  • 打赏
  • 举报
回复
报告楼上,VC6下编译通不过
lann64 2006-12-25
  • 打赏
  • 举报
回复
什么跟什么呀?
你定义的是友元函数,不是类成员函数。即使写在类定义内,它还是一个普通函数而不是类的成员函数。

operator<<是重载了其后第一个参数类型对应的"<<"操作。
只要你不重复定义,不会出现operator<< is ambiguous错误的。

#include <iostream>
#include <string>
using namespace std;
class student
{
public:
int key;
string name;
friend ostream & operator << (ostream &s,const student &k) ;
/*
{
cout << "in";
return s;
}
*/
friend void ff(student &s) ;
/*
{
cout<<s.name<<endl;
};
*/
student(){};
virtual ~student(){};
student(string &s);

};

student::student(string &s)
{
name=s;
}

ostream & operator << (ostream &s,const student &k)
{
cout<<"out";
//printf("name=%s,key=%d\n", k.name, k.key);
//printf("name=%s,key=%d\n", "k.name", 1);
return s;
}

void ff(student &s)
{
cout<<"out"<<endl;
}

int main()
{
string t="tim";
const student s1(t);
cout<<s1<<endl;
}
v2002750 2006-12-25
  • 打赏
  • 举报
回复
我本来也理解了,经楼上一说,我也糊涂鸟。
lpman2005 2006-12-25
  • 打赏
  • 举报
回复
VC6中涉及到输入输出流时在类外定义函数就有可能出现问题
.Net就不会出问题
crabscale 2006-12-25
  • 打赏
  • 举报
回复
我已糊涂了,刚才我还以为我理解了。(因为类里面的operator <<重载了全局名称空间了operator<<,所以在解析的时候出现了歧义,可经楼上一说这个解释就行不通了)
v2002750 2006-12-25
  • 打赏
  • 举报
回复
在类的前面加上
class student;
ostream & operator << (ostream &s,const student &k);
这样声明一下就好了。
至于ff为什么不用加上这个声明也能行,我就不理解了,因为类内部的声明不能导致类的外部被引进一个名字。我也是菜鸟,探索。
crabscale 2006-12-25
  • 打赏
  • 举报
回复
如果在类内不实现operator<<,同样也会出现operator<< is ambiguous的错误
crabscale 2006-12-25
  • 打赏
  • 举报
回复
那重载的operator <<呢?类内类外的声明是一样的啊
lann64 2006-12-25
  • 打赏
  • 举报
回复
友元函数可以在类内定义,也可以只在类内声明,在类外定义。(vc6对友元支持不好,只支持类内定义)。
但你不能类内类外都定义同一个函数。
v2002750 2006-12-25
  • 打赏
  • 举报
回复
ff函数给出了两个实体定义,当然有歧义了。
OOPhaisky 2006-12-25
  • 打赏
  • 举报
回复
友元函数可以定义在类的内部,也可以定义在类的外部,但是即使它定义在类内,它也是“全局函数”。
至于编译器的错误提示,可以不放在心上,也许其他编译器就会好一些。

64,281

社区成员

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

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