c++ 友元函数


友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。。类授予它的友元特别的访问权。通常同一个开发者会出于技术和非技术的原因,控制类的友元和成员函数(否则当你想更新你的类时,还要征得其它部分的拥有者的同意)。

定义格式(c++)

friend <;返回类型> <;函数名> (<;参数列表>);

分清成员函数,非成员函数和友元函数

成员函数和非成员函数最大的区别在于成员函数可以是虚拟的而非成员函数不行。所以,如果有个函数必须进行动态绑定(见条款38),就要采用虚拟函数,而虚拟函数必定是某个类的成员函数。关于这一点就这么简单。如果函数不必是虚拟的,情况就稍微复杂一点。(条款38: 决不要重新定义继承而来的缺省参数值)
更多,百度百科:http://baike.baidu.com/view/534170.htm
#include   
#include  
class Point  
{  
public:  
Point(double xx, double yy) { x=xx; y=yy; }  
void Getxy();  
friend double Distance(Point &a, Point &b);  
private:  
double x, y;  
};  
void Point::Getxy()  
{  
cout<<"("<<<","<<Y<<")"<<ENDL;< FONT>  
}  
double Distance(Point &a, Point &b)  
{  
double dx = a.x - b.x;  
double dy = a.y - b.y;  
return sqrt(dx*dx+dy*dy);  
}  
void main()  
{  
Point p1(3.0, 4.0), p2(6.0, 8.0);  
p1.Getxy();  
p2.Getxy();  
double d = Distance(p1, p2);  
cout<<"Distance is"<<  
FONT>
}

在面向对象的程序设计中,类的封装性使得我们使用类(对象)的成员数据时经常要通过类(对象)的成员函数。这对于类是一种保护。但在某些情况下,频繁的成员函数调用使得效率严重受损。

例如,定义矩阵类,并有两个矩阵对象相乘,为了获得矩阵中的元素值(私有成员),要频繁调用取值函数(公有成员)。

怎样可以提高效率?——使用友元函数。在C++中友元(friend)函数允许在类外访问该类中的任何成员,就象类的成员函数一样。

友元函数用关键字friend说明。下面用友元函数重载运算符“+”,以实现c=d+c。(即实数与复数的加法。)

◆ 1、定义友元函数的一般格式:
首先,在类声明里声明:
class Complex
{
……
friend Complex operator + (double,Complex);
};
/*opration+为类Complex类的友元函数, friend只用于类说明中 ……*/
第二步,在类外定义:
Complex operator + (double d , Complex c)
{
return Complex(d+c.Real , c.Image) ;
}

//注意友元不是成员函数,在类声明以外的地方也不加friend
第三步,使用,友元函数可以在任何地方直接访问类的私有成员
void main(void)
{
…… c=d+c1;
}

这里d+c1被C++编译器解释为operator+(d,c1),即调用友元函数operator+(d,c1)。

◆ 2、再进一步,如果使用友元函数
friend complex operator +(complex c1 , complexc2) ;
无论是复数与复数相加,还是实数与复数相加(不论实数在前还是在后)都可以用。为什么呢?

因为有此例所定义的缺省的构造函数,实数会被强制转换为虚部为零的复数。d+c1被解释为:
operator+(complex(d) , c1)

◆ 3、
friend Complex operator+(const Complex & c1,const Complex & c2)
{
……
}


这里采用Complex对象的引用而不是对象本身,调用时不再重新分配内存建立一个复制的对象,函数效率会更高。加const,实参只读,可防止实参被修改。

◆ 4、单目运算符前置“++”的友元函数重载方式如下:
Complex Complex::operator++(Complex & c )
{
return (++c.Real , ++c.Image) ;
}

采用友元函数方式定义与使用都很方便。但采用友元方式必须使用引用,因为被施加“++”运算的是一个参数。

◆ 5、友元函数重载后置“++”如下:
friend Complex operator++(Complex & c , int)
{
Complex temp=c;
c.Real++ , c.Image++ ;
return temp;
}

采用引用类型,实参c做了++,而temp是++前的值。

◆ 6、友元函数注意点:

    • 友元函数不是类的成员函数,在友元函数体中访问对象的成员,必须用对象名加运算符“.”加对象成员名。这一点和一般函数一样。但友元函数可以访问类中的所有成员(公有的、私有的、保护的),一般函数只能访问类中的公有成员;
    • 友元函数不受类中的访问权限关键字限制,可以把它放在类的公有、私有、保护部分,但结果一样;
    • 某类的友元函数的作用域并非该类域。如果该友元函数是另一类的成员函数,则其作用域为另一类的类域,否则与一般函数相同。
    • 友元函数破坏了面向对象程序设计类的封装性,所以友元函数如不是必须使用,则尽可能少用。或者用其他手段保证封装性。
      友元还有友元类概念,整个类可以是另一个类的友元。友元类的每个成员函数都是另一个类的友元函数,都可访问另一个类中的保护或私有数据成员。定义方法如下:
      class A
      {
      ……
      friend class B; //B为A的友元类
      ……
      };
优质内容筛选与推荐>>
1、Shell中的>/dev/null 2>&1 与 2>&1 >/dev/null 与&>/dev/null 的区别
2、linux命令(16):mv命令
3、【软工】第三次作业
4、获取指定日期 前 / 后 一天
5、js 推荐闭包一些实用的方法和一些注意事项(持续更新)


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn