c++中的类具有封装性,类中的私有数据只有该类的成员函数可以访问,程序中访问类中的私有成员,必须通过对象来调用成员函数,但是频繁的调用会使运行效率降低。

为了解决上述问题,c++中加入友元机制,友元可以不通过调用成员函数直接访问类的私有数据来提高运行效率。

友元可以是函数(友元函数)也可以是类(友元类)

友元函数:

  • 类体内说明,加friend关键字,在类体外定义,定义格式和普通函数相同。
  • 友元函数是非成员函数,调用上和普通函数相同。
  • 友元函数可以直接访问类中私有成员。

全局或函数做友元函数:

 #include<iostream>
#include<cmath>
using namespace std;
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 << "(" << x << "," << y << ")" << endl;
}
double Distance(Point &a, Point &b)
{
double dx = a.x -­‐ b.x;
double dy = a.y -­‐ b.y;
return sqrt(dx*dx + dy*dy);
}
int main(void)
{
Point p1(3.0, 4.0), p2(6.0, 8.0);
p1.Getxy();
p2.Getxy();
double d = Distance(p1, p2);
cout << "Distance is " << d << endl;
return ;
}

类成员函数做友元函数:

 #include<iostream>
#include<cmath>
using namespace std;
class Point;
//前向声明,是⼀一种不完全型声明,即只需提供类名(⽆无需提供类实现)即可。仅可⽤用 于声明指针和引
⽤用。
class ManagerPoint
{
public:
double Distance(Point &a, Point &b);
};
class Point
{
public:
Point(double xx, double yy)
{
x = xx;
y = yy;
}
void Getxy();
friend double ManagerPoint::Distance(Point &a, Point &b);
private:
double x, y;
};
void Point::Getxy()
{
cout << "(" << x << "," << y << ")" << endl;
}
double ManagerPoint::Distance(Point &a, Point &b)
{
double dx = a.x -­‐ b.x;
double dy = a.y -­‐ b.y;
return sqrt(dx*dx + dy*dy);
}
int main(void)
{
Point p1(3.0, 4.0), p2(6.0, 8.0);
p1.Getxy();
p2.Getxy();
ManagerPoint mp;
float d = mp.Distance(p1,p2);
cout << "Distance is " << d<< endl;
return ;
}

友元类:

  • 友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息
  • 格式;friend class 友元类名
  • 当说明一个类A是另一个类B的友元时,友元类A中所有成员函数都是另一个类B的友元函数
 #include <iostream>

 using namespace std;

 class X{
public:
friend class Y; //类Y 是类X 的友元类
void set(int i) { x=i; }
void display()
{
cout<<"x="<<x<<","<<"y="<<y<<endl;
}
private:
int x;
static int y; //静态数据说明
}; class Y
{
public:
Y(int i,int j);
void display();
private:
X a; //数据成员为类X的对象
}; int X::y=; //静态数据定义并初始化 Y::Y(int i,int j)
{
a.x=i; X::y=j;
} void Y::display()
{
cout<<"x="<<a.x<<","<<"y="<<X::y<<endl;
} int main()
{
X b;
b.set();
b.display();
Y c(,);
c.display();
b.display();
return ;
}

总结:

  1. 友元虽然提高了代码的运行效率,但是他破坏了类的封装性。
  2. 友元关系不可以被继承
  3. 友元关系是单向的,没有交换性
  4. 友元关系没有传递性

04 c++中的友元的更多相关文章

  1. 在ubuntu 16.04系统环境中搭建NAS(samba/iscsi/nfs)

    在ubuntu 16.04系统中搭建NAS环境 一.基本配置1:设置静态IPvi /etc/network/interfaces#iface ens32 inet dhcpiface ens32 in ...

  2. 在Ubuntu 12.04系统中安装配置OpenCV 2.4.3的方法

    在Ubuntu 12.04系统中安装配置OpenCV 2.4.3的方法   对于,在Linux系统下做图像识别,不像在windows下面我们可以利用Matlab中的图像工具箱来实现,我们必须借助Ope ...

  3. ubuntu14.04系统中virtualbox安装Oracle VM VirtualBox Extension Pack包

    ubuntu14.04系统中virtualbox默认不支持usb设备,需要安装Oracle VM VirtualBox Extension Pack才行,但必须安装以下版本才可以安装成功: Oracl ...

  4. 记录在Ubuntu 18.04系统中安装Apache, MySQL和PHP环境

    虽然我们在Linux VPS.服务器安装WEB环境比较方便,可以选择面板或者一键包,但是有些我们需要深入学习的网友不会选择一键安装,而是会尝试编译安装.这样可以学到一些内在的技术.一般我们较为习惯选择 ...

  5. C++中的友元函数和友元类

    C++中的友元函数主要应用于以下场景: 友元函数 第一种场景 代码中有一个全局函数,该函数想要去访问某个类的成员变量(该类的成员变量是private的,且该类并未提供任何获取获取私有成员变量的publ ...

  6. Ubuntu16.04系统中不同版本Python之间的转换

    Ubuntu系统自带的版本是2.7.12 安装好python3.6之后,改变一下Python的优先级(需要root权限). 在使用下面这个命令查看电脑里面有几个Python版本 update-alte ...

  7. 31. Ubuntu15.04系统中如何启用、禁用客人会话

    https://jingyan.baidu.com/article/046a7b3edf9639f9c27fa995.html 31. Ubuntu15.04系统中如何启用.禁用客人会话 听语音 | ...

  8. C#中实现C++中的友元类

    最近做一个小程序,一个类A(负责显示处理)需要大量调用类B(负责数据处理)的函数,我最先想到的C++中的友元概念,因为类B中的这些函数并不希望public,它只是允许类A调用监测. 网上搜索了一下,没 ...

  9. Ubuntu 18.04系统中不能ssh外网远程

    前言 今天我不小心动了电插板,导致服务器断电,用远程命令开机,居然很长时间没反应,索性就亲自按电源键重启.服务器正常开机启动,ssh可以内网访问,远程命令内网有效果,就是外网不行.经过分析排查,是不是 ...

随机推荐

  1. 【Python学习之十】操作数据库

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 python3.6 操作mysql数据库 1.安装pymysql模块p ...

  2. ENSP静态链路聚合实验配置要点及实例

    链路聚合分为:静态链路聚合.动态链路聚合链路聚合的负载分担模式:对于二层数据流,系统会根据MAC地址(源mac地址和目的mac地址来计算),而对于三层数据流则会根据ip地址来进行负载分担计算. 静态链 ...

  3. 【剑指offer】面试题 18. 删除链表的节点

    面试题 18. 删除链表的节点

  4. springboot继承JpaRepository报org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualif

    在SpringBoot项目中使用JPA时总是报注入失败,不能创建继承JpaRepository的类的问题,然后尝试给继承JpaRepository的写个实现类,不出现注入失败的情况,但是过一段时间后继 ...

  5. java笔记3

    面向对象的特点:   1.封装:   2.继承   3.多态 好处:   是一种符合人们思考习惯的思想  可以将复杂的事情简单化  将程序员从执行者变为指挥者 二 类与对象 成员变量与局部变量的区别: ...

  6. gorm 批量插入数据

    使用gorm 插入数据的时候,根据官方文档可以使用Create或者FirstOrCreate(). 但是官方没有提供批量插入数据的方法. 根据github的 issue得知,我们可以通过自己拼接sql ...

  7. AS3灰色图像

    一开始觉得AS3的滤镜很难使用,尤其是那些矩阵,让人望而生畏.最近写一个聊天模块,要用到离线状态下的灰色头像,于是认真研究了ColorMatrixFilter,发现其实也没有那么难.所谓的矩阵其实就是 ...

  8. (四)pdf的构成之文件体(树图)

    pdf的文件体类似于一个大树 有个根对象(catalog),该对象中保存着PDF的很多基本信息,并通过间接引用,辐射到所有的间接对象. (下图是大概的树形状)

  9. 3.01定义常量之define

    [注:本程序验证是使用vs2013版] #include <stdio.h> #include <stdlib.h> #include <string.h> #pr ...

  10. HDFS-HA高可用集群搭建

    HA高可用集群搭建 1.总体集群规划 在hadoop102.hadoop103和hadoop104三个节点上部署Zookeeper. hadoop102 hadoop103 hadoop104 Nam ...