C++使用类对数据进行隐藏和封装,类的数据成员一般定义为私有成员,而将提供类与外界通讯接口的成员函数定义为公有的。

C++类成员的三种访问权限:

  • public:可以被该类中的函数、子类的函数、友元函数访问,也可以由该类的对象访问;
  • protected:可以被该类中的函数、子类的函数、友元函数访问,但不可以由该类的对象访问;
  • private:可以被该类中的函数、友元函数访问,但不可以由子类的函数、该类的对象、访问。

但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁访问类的私有(private)成员和保护(protected)成员,这时可以将这些函数定义为友元函数。

除了友元函数,还有友元类,两者统称为友元(friend)。

借助友元,可以使得普通函数或其他类中的成员函数可以访问某个类的私有成员和保护成员。

  • 友元函数:普通函数可以访问某个类私有成员或保护成员。
  • 友元类:类A中的成员函数可以访问类B中的私有或保护成员。

1、友元函数

友元函数时可以直接访问类的私有成员或保护成员,它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明。

友元函数的声明格式如下:

friend 类型 函数名(形参);

示例如下,友元函数 ShowAge() :

如上图所示,类的友元函数 ShowAge() 定义在类的外部,需要注意的是,尽管 ShowAge() 在类的定义中出现过,但其并不是类的成员函数。

倘若没有在 Student 类中声明友元函数 ShowAge() ,则其是不能直接访问类的私有成员的,如下图所示。

类的友元函数函数减少了类型检查和安全性检查,提高了程序的运行效率,但它破坏了类的封装性和隐藏性,使得非成员函数也可以访问类的私有成员。

2、友元类

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

友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的保护成员和私有成员。

声明友元类的格式如下:

friend class 类名;

其中,friend 和 class 是关键字,类名必须是程序中已经定义过的一个类。

示例如下,类CB是类CA的友元类,可以直接访问类CA的私有成员。

倘若没有在类CA中声明友元类CB,则CB是不能直接访问CA的私有成员的。

使用友元类时,需要注意:

  • 友元关系不能被继承;
  • 友元关系是单向的,不具有交换性。即类B是类A的友元,则类A不一定是类B的友元,需要看类中是否有相应的声明;
  • 友元关系不具有传递性。即类B是类A的友元,类C是类B的友元,但类C不一定是类A的友元,需要看类中是否有相应的声明。

另外,使用一般不建议把整个类声明为友元类,而只将某些成员函数声明为友元函数,这样更安全些。

3、友元的优缺点

利用 friend 修饰符,可以让一些普通函数 或 另一个类的成员函数 直接对某个类的保护成员和私有成员进行操作,提高了程序的运行效率;同时避免把类的成员都声明为public,最大限度地保护数据成员的安全。

但是,即使是最大限度地保护数据成员,友元也破坏了类的封装性。

如果将类的封装比喻成一堵墙的话,那么友元机制就像墙上开了一个门。所以使用友元时一定要慎重。

友元函数可以访问私有成员吗_C++的友元函数和友元类相关推荐

  1. 为什么静态成员函数可以访问私有成员变量?(访问控制是针对类而不是针对对象)

    访问控制是针对类而不是针对对象 先看几个标准定义 A member of a class can be - private; that is, its name can be used only by ...

  2. 学习笔记-----关于C++中类的成员函数可以访问私有成员的问题

    直接上代码吧 template<class T> class vectorList : public linearList<T> { public: vectorList(si ...

  3. 关于对象不能直接访问私有成员的误区(转)

    先贴代码: #includeusing namespace std; class CPoint {public:CPoint(int xx, int yy){x = xx;y = yy;}CPoint ...

  4. C++ 单继承访问私有成员

    c++ 单继承之如何调用私有成员 #include <iostream> #include <string> using namespace std; class Person ...

  5. C#中访问私有成员技巧

    源代码是别人的,你就不能修改源代码,只提供给你dll.或者你去维护别人的代码,源代码却有丢失.这样的情况如果你想知道私有成员的值,甚至去想直接调用类里面的私有方法.那怎么办呢?其实在.net中访问私有 ...

  6. 设计一个圆类(circle),内有私有成员radius代表半径, 函数get_radius( )用于获得半径、area( )用于计算圆的面积; (2)定义一个桌子类table,内有私有数据h

    1.(1)设计一个圆类(circle),内有私有成员radius代表半径, 函数get_radius( )用于获得半径.area( )用于计算圆的面积: (2)定义一个桌子类table,内有私有数据h ...

  7. 把类的成员函数声明为友元函数,但不能访问私有成员的原因和解决办法

    定义类X,类Y,在类X中声明类Y的成员函数g()为类X的友元函数 常见的几种错误写法及原因: 错误写法1 class Y; class X {public:X(int i) :i(i) {}frien ...

  8. C++友元函数访问私有成员

    #include<iostream> using namespace std; class CTimeInfo { public: void setTime();//默认函数构造 void ...

  9. 3第一周课后练习#183;阅读计划(3)-使用函数来访问私有数据成员

    /** Copyright (c) 2015, 计算机科学学院,烟台大学* All rights reserved.* 文件名:test.cpp* 作 靠:刘畅* 完成日期:2015年 3 一个月 2 ...

最新文章

  1. 成功解决Could not import the PyAudio C module ‘_portaudio‘.
  2. 为什么敏捷方法能在软件开发中行之有效?
  3. python获取文件夹下文件_Python获取目录下的所有文件
  4. java 图片分割_Java atlas图集分割
  5. 阿里双十一秒杀系统架构设计,有哪些技术关键点?
  6. Nacos支持配置的动态更新
  7. 聊聊HystrixEventNotifier
  8. 如何使用Chrome command API查找SAP Spartacus的router-outlet
  9. mac解压rar命令_苹果mac电脑上很好用的免费压缩软件?ezip压缩软件分享
  10. iOS:界面适配(二)--iPhone/iPad适配(关于xib)
  11. linux下列目录清单用命令,Linux入门必看的Is命令实用范例!
  12. mybatis + spring + PostgreSQL使用中的问题一例
  13. 自动驾驶传感器---毫米波雷达原理(测距、测速、角速度测量),毫米波雷达系统构成
  14. 游戏对战平台研究终结
  15. 自然语言处理——中英文分词工具(还可做词性标注与命名实体识别)
  16. oracle下的inventory文件夹,Oracle中Inventory目录作用以及如何重建此目录
  17. 将IP地址转换为整数--将32位的二进制转换为十进制
  18. 如何制作马赛克是硬质纤维板应该正确基金会对于马赛克
  19. 小程序开发API之地图wx.createMapContext及MapContext 实例
  20. En-Tan-Mo(ETM)项目周报(7.5-7.11)

热门文章

  1. 【Spring】Spring Eureka Client 注册报 registration status: 204
  2. 90-40-009-源码-CUBE-引擎为Spark写入Hbase本
  3. 【Elasticsearch】es查看有问题的索引或者分片
  4. 【Elasticsearch】elasticsearch 7.x 查看分片未分配 (UNASSIGNED) 的原因
  5. RocketMQ : RemotingTooMuchRequestException: sendDefaultImpl call timeout
  6. php怎么构造一个验证码,PHP封装一个生成验证码的函数
  7. 数据库编程--SqlServer示例
  8. Latex数学符号对应表
  9. java基础面试题之:String 类的常用方法都有那些?
  10. scrap连接django