友元函数和友元类

摘要:
友元函数和友元类问题的提出我们已知道类具有封装和信息隐藏的特性。友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。友元函数友元函数的特点是能够访问类中的私有成员的非成员函数。.类必须将重载函数集中每一个希望设为友元的函数都声明为友元。该基类的派生类不能访问授予友元关系的类。

友元函数和友元类

问题的提出

我们已知道类具有封装和信息隐藏的特性。只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性。另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运行效率。

为了解决上述问题,提出一种使用友元的方案。友元是一种定义在类外部的普通函数,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是它可以访问类中的私有成员。友元的作用在于提高程序的运行效率,但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。

友元函数

友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样。下面举一例子说明友元函数的应用。

#include 
  #include 

  classPoint
  {
  public:
    Point(double xx, double yy) { x=xx; y=yy; }
    voidGetxy();
    friend double Distance(Point &a, Point &b);
  private:
    doublex, y;
  };

  voidPoint::Getxy()
  {
  cout<<"("<}

  double Distance(Point &a, Point &b)
  {
  double dx = a.x -b.x;
  double dy = a.y -b.y;
  return sqrt(dx*dx+dy*dy);
  }

  voidmain()
  {
  Point p1(3.0, 4.0), p2(6.0, 8.0);
  p1.Getxy();
  p2.Getxy();
  double d =Distance(p1, p2);
  cout<<"Distance is"<}

说明:在该程序中的Point类中说明了一个友元函数Distance(),它在说明时前边加friend关键字,标识它不是成员函数,而是友元函数。它的定义方法与普通函数定义一样,而不同于成员函数的定义,因为它不需要指出所属的类。但是,它可以引用类中的私有成员,函数体中a.x,b.x,a.y,b.y都是类的私有成员,它们是通过对象引用的。在调用友元函数时,也是同普通函数的调用一样,不要像成员函数那样调用。本例中,p1.Getxy()和p2.Getxy()这是成员函数的调用,要用对象来表示。而Distance(p1, p2)是友元函数的调用,它直接调用,不需要对象表示,它的参数是对象。该程序的功能是已知两点坐标,求出两点的距离。

友元类 :

友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。 当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。定义友元类的语句格式如下: friend class 类名; 其中:friend和class是关键字,类名必须是程序中的一个已定义过的类。

例如,以下语句说明类B是类A的友元类:

   classA
      {
             …
      public:
             friend classB;
             …
      };

经过以上说明后,类B的所有成员函数都是类A的友元函数,能存取类A的私有成员和保护成员。

使用友元类时注意

(1) 友元关系不能被继承

(2) 友元关系是单向的,不具有交换性。若类B是类A的友元,类A不一定是类B的友元,要看在类中是否有相应的声明。

(3) 友元关系不具有传递性。若类B是类A的友元,类C是B的友元,类C不一定是类A的友元,同样要看类中是否有相应的申明

注意事项

(1).友元可以访问类的私有成员。

(2).只能出现在类定义内部,友元声明可以在类中的任何地方,一般放在类定义的开始或结尾。

(3).友元可以是普通的非成员函数,或前面定义的其他类的成员函数,或整个类。

(4).类必须将重载函数集中每一个希望设为友元的函数都声明为友元。

(5).友元关系不能继承,基类的友元对派生类的成员没有特殊的访问权限。如果基类被授予友元关系,则只有基类具有特殊的访问权限。该基类的派生类不能访问授予友元关系的类。

免责声明:文章转载自《友元函数和友元类》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇HTML5+CSS3学习笔记(二)使用 Spring Security 保护 Web 应用的安全下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

类3(友元)

一、友元介绍 我们知道,类的成员函数可以访问同类的其他成员函数,包括公有、私有和保护成员。而类的外部函数只能访问类的公有成员。友元是一种允许非类成员函数访问类的非公有成员的一种机制。可以把一个函数指定为类的友元,也可以把整个类指定为另一个类的友元。 友元函数友元类 二、友元函数友元函数在类作用域外定义,但它需要在类体中进行说明为了与该类的成员函数加以区别,...

友元

  友元主要是为了访问类中的私有成员(包括属性和方法),可以分为友元函数(全局函数),友元类,友元成员函数。 全局函数做友元函数   友元函数是可以直接访问类的私有成员。它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时在函数名称前加上关键字friend,其格式如下: friend 类型 函数名(形式参数);   注意:(1)友元...

window下安装itchat库

itchat是一个开源的微信个人号接口,使用python调用微信从未如此简单。 pip 是 Python 著名的包管理工具,在 Python 开发中必不可少。 1、安装   检查你有没有安装了pip:运行,输入cmd,回车,输入pip,回车。如果提示“'pip' 不是内部或外部命令”,原因是电脑本地没有安装pip命令。   这有两种办法安装pip:   A...

再来说说LumaQQ.NET怎么发群消息

        QQ群有两个ID,内部ID和外部ID。外部ID就是我们平时常见的ID,搜索啊,查看啊,都是这个ID。         而内部ID就不常见了,应该说用QQ的人是从来不知道还有这个ID的。但是,这个ID是这篇文章的重点。因为发群信息必须用到这个ID。         用过LumaQQ.NET的人,尝试过用QQ上可见的群号码发群消息,相信都是超...

C++ 友元

https://blog.csdn.net/fanyun_01/article/details/79122916 在C++中,我们使用类对数据进行了隐藏和封装,类的数据成员一般都定义为私有成员,成员函数一般都定义为公有的,以此提供类与外界的通讯接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为...