friend ostream& operator << (ostream& os,complex& c);
敬请高手详细讲解一下此处的 << 重载的原理,不胜感激!
(现手头资料太少,给点资料也好)
class complex{
public:
complex(){Re=Im=0;}
complex& operator= (complex& ob){Re=ob.Re;Im=ob.Im;}
complex& operator+ (complex& ob);
friend ostream& operator << (ostream& os,complex& c); //此处
private:
double Re,Im;
};
friend ostream & operator << (ostream& os,complex& c){
return os<<ob.Re<<(ob.Im>=0.0)?"+":"-"<<fabs(ob.Im)<<"i";
}
(1)用friend 的好处是?主要为了解决什么问题?
(2)参数为什么是:ostream& os,complex& c ?
(3)这一句 return os<<ob.Re<<(ob.Im>=0.0)?"+":"-"<<fabs(ob.Im)<<"i"; 里面的os<<ob.Re如何理解?
再次感谢!
问题点数:20、回复次数:17Top
1 楼brisk(11)回复于 2003-12-02 22:51:25 得分 4
1.用friend 主要为了解决什么问题?
C++类中,在private域和protected域中声明的数据成员和成员函数构成了类的私有部分,只能由该类的对象和成员函数,以及被声明为friend(友元)的函数或类的对象访问。Top
2 楼brisk(11)回复于 2003-12-02 23:03:10 得分 0
2.操作符重载的问题
在类的公共域中声明作为友元函数定义的用于流输入的重载操作符“<<”,它不是类的成员函数,但是这样做可以向对字符串那样简单的实现对类complex实例变量的输入操作. 我这一段常用这个,但也是说不明白。呵呵Top
3 楼kdush(迷茫过后……还是迷茫……) (love—>kula始终未变)回复于 2003-12-02 23:17:59 得分 4
(1):friend 可以访问其友元类的protected和private成员,它可以不破坏类的封装性。
(2):ostream &os 是对os的引用,在运算符<<重载时好象都有这个ostream&.complex &c是对一个complex 对象c的引用。
(3):这一句是先输出类complex 的对象ob.Re然后判断ob.>=0.0么?如果>=0.0就输出+
在重载<<时必须把它设成友元函数。因为在运算符重载时,运算符函数是一个成员函数,其左值必须是类的一个对象,(或是对该类对象的引用)。如果左边的操作数必须是一个不同类的对象,该运算符函数必须作为一个非成员函数来实现。
<< 其左值不可能是该类的一个对象,所以必须用友元来实现<<的重载!
第一处friend ostream& operator << (ostream& os,complex& c);
也可以写成这样:
friend ostream& operator << (ostream& ,complex& );
Top
4 楼zhuangzhou(当时间也被挥霍一空,我还会有什么?)回复于 2003-12-03 07:55:42 得分 0
谢谢 活跃和库拉Top
5 楼zhuangzhou(当时间也被挥霍一空,我还会有什么?)回复于 2003-12-03 08:29:52 得分 0
#ifndef _complex_h_
#define _complex_h_
#include <iostream.h>
class complex{
public:
complex(){Re=Im=0.0;}
complex(double r){Re=r;Im=0;}
complex(double r,double i){Re=r;Im=i;}
double getReal(){return Re;}
double getImag(){return Im;}
void setReal(double r){Re=r;}
void setImag(double i){Im=i;}
complex& operator= (complex& ob){Re=ob.Re;Im=ob.Im;}
complex& operator+ (complex& ob);
friend ostream & operator<< (ostream & os,complex & c); //Reload operator <<
private:
double Re,Im;
};
#endif
#include <iostream.h>
#include <math.h>
#include "complex.h"
complex& complex::operator+ (complex& ob){
complex* result=new complex(Re+ob.Re,Im+ob.Im);
return *result;
}
friend ostream & operator << (ostream & os,complex & ob){
return os<<ob.Re<<(ob.Im>=0.0)?"+":"-"<<fabs(ob.Im)<<"i\n";
}
//complex.h 是complex的声明,complex.cpp 是complex的函数的实现,vc6编译出错:
(1)g:\cpp\reload\complex.cpp(10) : error C2255: '<<' : a friend function can only be declared in a class
(2)g:\cpp\reload\complex.cpp(10) : error C2556: 'void __cdecl operator <<(class ostream &,class complex &)' : overloaded function differs only by return type from 'class ostream &__cdecl operator <<(class ostream &,class complex &)'
(3)g:\cpp\reload\complex.h(16) : see declaration of '<<'
(4)g:\cpp\reload\complex.cpp(11) : error C2296: '<<' : illegal, left operand has type 'char [2]'
g:\cpp\reload\complex.cpp(11) : error C2297: '<<' : illegal, right operand has type 'double'
main.cpp
Error executing cl.exe.
哪位给解释一下错在哪里?谢谢!Top
6 楼hanyixin(怡)回复于 2003-12-03 08:57:31 得分 4
在类外定义这个friend函数的时候,就不要再加friend了。
Top
7 楼zhuangzhou(当时间也被挥霍一空,我还会有什么?)回复于 2003-12-03 10:29:35 得分 0
第四个错误是怎么回事?
error C2296: '<<' : illegal, left operand has type 'char [2]'
error C2297: '<<' : illegal, right operand has type 'double'
Top
8 楼5852(我在Cplusplus门外吗,加油)回复于 2003-12-03 12:37:54 得分 8
这句有问题:return os<<ob.Re<<(ob.Im>=0.0)?"+":"-"<<fabs(ob.Im)<<"i\n";
该成: return os<<ob.Re<<((ob.Im>=0.0)?‘+’:‘-’)<<fabs(ob.Im)<<"i\n";
原因:“+” 字符串 ‘+’字符
至于为什么加括号 我不知道为什么 不过加了以后就没错了 很多情况下宁可多加一个括号 也不要让编译器费事 产生莫名的错误
另外 楼主 你的+重载估计有问题 你test一下
Top
9 楼heguobaoceo(awen)回复于 2003-12-03 13:04:19 得分 0
friend函数可以访问由private域和protected域中声明的数据成员和成员函数
ostream& os,complex& c 中的ostream& os,定义os<<它相当于cout<<
Top
10 楼zhuangzhou(当时间也被挥霍一空,我还会有什么?)回复于 2003-12-03 16:46:49 得分 0
5852(我在Cplusplus门外吗,加油)
谢谢你的解决方案,我只加了一个括号就搞定了;
另外,刚刚test了一下,+重载能够正确执行
Top
11 楼5852(我在Cplusplus门外吗,加油)回复于 2003-12-03 21:57:35 得分 0
楼主 但是你看一看构造函数和析构函数的执行情况 你就发现 你这样写会有问题发生的 当然你表面上没看到问题Top
12 楼5852(我在Cplusplus门外吗,加油)回复于 2003-12-03 21:59:13 得分 0
还有这里complex& operator= (complex& ob){Re=ob.Re;Im=ob.Im;}
也有问题
Top
13 楼zhuangzhou(当时间也被挥霍一空,我还会有什么?)回复于 2003-12-04 07:51:49 得分 0
哦,不好意思,可能是我没把代码全贴出来的事
下面是一个完整的代码,请5852(我在Cplusplus门外吗,加油) 指正:
#ifndef _complex_h_
#define _complex_h_
#include <iostream.h>
//complex.h
class complex{
public:
complex(){Re=Im=0.0;}
complex(double r){Re=r;Im=0;}
complex(double r,double i){Re=r;Im=i;}
double getReal(){return Re;}
double getImag(){return Im;}
void setReal(double r){Re=r;}
void setImag(double i){Im=i;}
complex& operator= (complex& ob){Re=ob.Re;Im=ob.Im;}
complex& operator+ (complex& ob);
friend ostream & operator<< (ostream & os,complex & c); //Reload operator <<
private:
double Re,Im;
};
#endif
//complex.cpp
#include <iostream.h>
#include <math.h>
#include "complex.h"
complex& complex::operator+ (complex& ob){
complex* result=new complex(Re+ob.Re,Im+ob.Im);
return *result;
}
ostream & operator << (ostream & os,complex & ob){
return os<<ob.Re<<((ob.Im>=0.0)?"+":"-")<<fabs(ob.Im)<<"i\n";
}
//main.cpp
#include <iostream.h>
#include <string>
#include <stdlib.h>
#include "complex.h"
using namespace std;
int main()
{
double edition=0.021;
cout<<edition<<endl;
complex c1=complex(1,2);
complex c2=complex(10,20);
complex c3=c1+c2+c1;
cout<<c3;
return 0;
}
//我觉得没什么错啊?能否探讨一下?Top
14 楼5852(我在Cplusplus门外吗,加油)回复于 2003-12-04 09:38:45 得分 0
1.complex& operator= 这个函数没返回值 建议添加 reurn *this;
2.complex& operator +
返回值是一个引用,而你返回的是一个用new创建的局部变量,new和delete的应该成对出现,
此处确只有new 那么什么地方才会调用delete的呢?我建议你在构造函数里添加输出提示:
cout<< "Constructor called"析构函数里添加提示cout<< "Destructor called",我相信你从输出结果就可以看出问题了(好像楼主也忘记了定义析构函数:p)
Top
15 楼zhuangzhou(当时间也被挥霍一空,我还会有什么?)回复于 2003-12-04 15:21:14 得分 0
不好意思,这是从数据结构上看到的一个例程
刚刚接触C++,多谢指教!Top
16 楼5852(我在Cplusplus门外吗,加油)回复于 2003-12-04 21:21:12 得分 0
共同学习吧 我也没学多久Top
17 楼zhuangzhou(当时间也被挥霍一空,我还会有什么?)回复于 2003-12-08 17:48:20 得分 0
呵呵,结了吧,以后多交流Top




