友元函数
这个程序使用了操作符重载函数
#include<iostream.h>
class a
{
private :
int i;
public:
a()
{
i=1;
}
a(int x)
{
i=x;
}
display()
{
cout<<i;
}
a& operator *(int num) //操作符重载函数
{
this->i=this->i*num;
return (*this);
}
};
void main()
{
a a1(10);
a a2;
a2=a1*20; //这里调用了操作符重载函数 a2=a1.operator *(int 20)
a2.display() ;
}
这个程序运行没有任何问题,只是不明白一点
第一个问题:重载函数中为什么要返回引用,有什么意义,我试了一下,去掉它结果也是没问题的,帮解释一下。
请再看这个程序
#include<iostream.h>
class a
{
private :
int i;
public:
a()
{
i=1;
}
a(int x)
{
i=x;
}
display()
{
cout<<i;
}
a& operator *(int num)
{
this->i=this->i*num;
return (*this);
}
friend a& operator *(int num,a &temp);//?这里为什么要声明成友元,去掉它为什么会报错,构成重载不可以吗?
};
a& operator *(int num,a &temp)
{
return (temp*num);
}
void main()
{
a a1(10);
a a2;
a2=20*a1;//?显示调用的格式的什么?是不是a2=20.operator*(a &a1)?这里用友元是解决这种格式的问题,可为什么使用友元能解决这种问题?
a2.display() ;
}
这个程序和上个程序的区别是上面那个是a2=a1*20;这个程序是a2=20*a1;这个语句对编译器来说没有意义,要想正常运行程序,需要使用友元函数解决这个问题。
第二个问题:为什么要用友元函数,我知道友元函数是为了访问其他类中的成员的,这里使用友元来解决这个问题,不大理解,去掉friend还报错,为什么?
第三个问题:a2=20*a1;显示调用的格式是什么??
问题点数:30、回复次数:9Top
1 楼hyallentong(Caniggia)回复于 2006-03-16 16:50:19 得分 3
重载函数中为什么要返回引用?
实现连乘 如 a1*a2*a3……Top
2 楼yinqing_yx(淘汰引擎)(玩虚一族)回复于 2006-03-16 16:53:35 得分 4
第一个问题:重载函数中为什么要返回引用,有什么意义,我试了一下,去掉它结果也是没问题的
答:用于实现链式表达
第二个问题:为什么要用友元函数,我知道友元函数是为了访问其他类中的成员的,这里使用友元来解决这个问题,不大理解,去掉friend还报错,为什么?
答:流插入操作符必须有一个类型为ostream&的左操作符,因此必须是一个非成员函数。而他们需要访问类的private成员,所以需要为友元函数
第三个问题:a2=20*a1;显示调用的格式是什么??
答: 20*a1 --------> a1& operator*( 20 )
a2 = a1 赋值操作符~
Top
3 楼discory(discory)回复于 2006-03-16 17:28:09 得分 3
第一个问题我知道一点,单操作符重载只能重载左值,所以a2=a1*20对,
a2=20*a1不可能重载20,我也刚看到这里,不是很清楚Top
4 楼WonderInJYC(Learn_晕ing)回复于 2006-03-16 17:36:34 得分 3
第二个问题:friend a& operator *(int num,a &temp);//?这里为什么要声明成友元,去掉它为什么会报错,构成重载不可以吗?
因为重载二元运算符时,用成员函数重载,它的左操作数必须为该类的对象.而友元函数则可以处理左右操作数不同的问题.Top
5 楼yuchen2006(雨晨)回复于 2006-03-16 18:26:40 得分 0
第二个问题:为什么要用友元函数,我知道友元函数是为了访问其他类中的成员的,这里使用友元来解决这个问题,不大理解,去掉friend还报错,为什么?
答:流插入操作符必须有一个类型为ostream&的左操作符,因此必须是一个非成员函数。而他们需要访问类的private成员,所以需要为友元函数
第三个问题:a2=20*a1;显示调用的格式是什么??
答: 20*a1 --------> a1& operator*( 20 )
a2 = a1 赋值操作符~
"流插入操作符必须有一个类型为ostream&的左操作符"这句话的意思不明白,请帮解释,这里又流插入操作符吗??
我想a2=20*a1;是先调用的友元吧,然后友元中的temp*num调用了原来的操作符重载函数,如果是这样,a1& operator*( 20 )这种格式就不大明白了
Top
6 楼ugg(逸学堂(exuetang.net))回复于 2006-03-16 20:26:26 得分 15
第一个问题:重载函数中为什么要返回引用,有什么意义,我试了一下,去掉它结果也是没问题的,帮解释一下。
~~~~~~~~~
这个问题,首先明白返回引用和返回对象的区别,返回对象,要生成临时对象,lz可以通过跟随
对象的创建次数来测试。这时就会知道引用和返回对象的区别。
还有一个就是炼成的问题,a1 = a1*a2*a3;如果不返回引用,将无法实现炼成。
第二个问题:为什么要用友元函数,我知道友元函数是为了访问其他类中的成员的,这里使用友元来解决这个问题,不大理解,去掉friend还报错,为什么?
第三个问题:a2=20*a1;显示调用的格式是什么??
其实二三关键就是对a1*20,和20*a1的理解,编译器要对表达式进行操作时,
首先要把表达式中的类型转换为相同类型,比如处理a1*20式,编译器首先找到
a1的类型,所以要利用a1对象中的*操作符号,但是发现*运算符,要求输入的是
int型,所以这时可以直接调用a1.operator*(20),其实如果lz修改为a& operator *(consta& num)这样上面的操作也会成立,因为编译器会把a的构造函数a(int x)把20身成一个a类型对象。
所以上面的修改会成功。
但是20*a1;编译器会想法把a1转换为int型进行操作。如果lz不用friend,可以重载int操作符号
operator int() const
{
return i;
}
这样上面的表达式也正确,不会出错。
只是声明为friend后,20*a1;调用格式为
operator(20,a1);
Top
7 楼edwardrong(明年-今日)回复于 2006-03-17 01:45:48 得分 2
ugg(逸学堂(exuetang.net))
还有一个就是炼成的问题,a1 = a1*a2*a3;如果不返回引用,将无法实现炼成。
~~~~~~~~~~~~~~~~~~~~~~~~~
请问关于这点能给出一个例子解释一下吗?Top
8 楼yuchen2006(雨晨)回复于 2006-03-17 06:11:53 得分 0
ugg(逸学堂(exuetang.net))
还有一个就是炼成的问题,a1 = a1*a2*a3;如果不返回引用,将无法实现炼成。
~~~~~~~~~~~~~~~~~~~~~~~~~
请问关于这点能给出一个例子解释一下吗?
我试了试,不用返回引用没有问题啊,帮忙举个例子吧,多谢了
下面是我试的程序,没有返回引用
#include<iostream.h>
class A
{
int aa;
public:
A(int x)
{
aa=x;
}
A operator *(A duixiang)
{
this->aa=this->aa*duixiang.aa;
return(*this);
}
void display()
{
cout<<aa<<endl;
}
};
void main()
{
A a1(2),a2(3),a3(4);
a1=a1*a2*a3;
a1.display();
}Top
9 楼ugg(逸学堂(exuetang.net))回复于 2006-03-17 09:20:24 得分 0
a1 = a1*a2*a3;
~~~~~~~
上面的函数调用过程如下
a1.operator=(a1.operator*(a2.operator*(a3));
这里的主要问题是连乘出问题,而不是等号出问题。
所以楼上按下面的方法进行测试
a1*a2*a3;
a1.display();
在使用&符号后,a1可以得到正确值24,如果不是用引用符号,a1的值会为6。
这就是区别。而上面例子中由于使用=,相当于把连乘后的结果值赋值给a1,
而这个结果是一个临时对象,采用引用时使用=,这时只是相当于
a1*a2*a3;
a1=a1;
Top




