C++中友元函数(friend)解析

 文章转自公众号:Coder梁(ID:Coder_LT)

我们知道C++控制对象的私有部分的访问,只能通过公共的接口。这样的设计当然没错,但有的时候也会显得过于严格,产生一些问题。

因此C++提供了另外一种形式的访问权限,叫做友元(friend)。

友元有三种,分别是友元函数、友元类和友元成员函数。

通过让函数成为类的友元,可以赋予该函数与类成员函数一样的访问权限,也就是说我们可以在友元函数当中访问类的私有成员变量。

在介绍友元函数的使用之前,我们需要先了解为什么需要友元函数。C++ Primer中给了一个非常不错的例子,在之前运算符重载的例子当中,我们实现了一个类Time。用来记录时间,假设我们需要重载它的*运算符,能够允许一个时间对象和一个浮点数相乘。

很明显,我们只需要重载运算符*即可:

Time Time::operator*(const double x) {
    // todo
}

我们在使用的时候大概是这样:

Time a, b;
a = b * 32.5;

但是这里有一个小问题,我们写成a = b * 32.5;可以,但如果反过来写成32.5 * b就不行了。因为对于b * 32.5来说本质上是b调用了operator*函数,等价于a = b.opeartor*(32.5);。但后者就不行了,要怎么解决呢,只能另外实现一个函数来解决了,这个函数有两个input,分别是doubleTime类型,返回一个Time类型。

Time operator*(double m, const Time &t);

但这又有了新的问题,由于这不是一个成员函数,不能直接访问类的私有数据。为了破例让它能够访问,我们需要将它设置成友元。

创建友元的方法很简单,我们只需要在函数签名之前加上关键字friend

friend Time operator*(double m, const Time &t);

它有两个含义:

  • 它不是成员函数,因此不能使用成员函数运算符来调用
  • 它与成员函数的访问权限相同,即可以访问所有privatepublic数据

由于友元函数不是成员函数,所有我们在实现的时候不需要使用Time::限定符,也不用在实现当中加上关键字friend

函数的实现如下:

Time operator*(double m, const Time &t) {
    Time result;
    long totalminutes = t.hours * m * 60 + t.minutes * m;
    result.hours = totalminutes / 60;
    result.minutes = totalminutes % 60;
    return result;
}

我们在函数当中直接访问了hoursminutes成员变量,因此函数必须是友元函数。

当然我们可以把函数稍微变换一下,就可以不必是友元函数了:

Time operator*(double m, const Time &t) {
    return t * m; //  调用了t.operator*(m)
}

在这个函数当中,我们没有显式地访问私有变量,因此可以不必是友元。

到此这篇关于C++友元函数讲解的文章就介绍到这了,更多相关C++友元函数内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 在C++中关于友元函数的进一步理解

    这里重新将类的成员函数的定义看一下: 百科上的认识: 类的成员函数的原型要写在类体中,原型说明了函数的参数表和返回值类型.而函数的定义一般在类外面,也可以直接在类内部定义.前者与普通函数不同的是,实现成员函数时要指明类的名称,具体形式为: 返回值类型 类名 :函数成员名(参数表){函数体}: 而后者一般为一些短小的函数(5行以内),也就是内联函数. 这里在百科上对友元函数的解释: 友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数.类授予它的友元特别的访问权.通常同一个开发者会出于技术和

  • 剖析C++编程中friend关键字所修饰的友元函数和友元类

    在某些情况下,为不是类成员的函数或单独类中的所有函数授予成员级别的访问权会更方便.仅类实现器可以声明其友元.函数或类不能将其自身声明为任何类的友元.在类声明中,使用 friend 关键字和非成员函数名称或其他类,以允许其访问你的类的专用和受保护成员. 语法 friend class-name; friend function-declarator; 友元声明 如果声明以前未声明的友元函数,则该函数将被导出到封闭非类范围. 友元声明中声明的函数被视为已使用 extern 关键字声明.(有关 ext

  • C++中的friend友元函数详细解析

    友元函数是可以直接访问类的私有成员的非成员函数.它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend. 我们已知道类具有封装和信息隐藏的特性.只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的.非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性.另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运

  • 关于C++友元函数的实现讲解

    友元函数是一种特殊的函数,它必须要在类中进行声明,但其本身并不是类的成员函数,但友元函数可以访问类的私有成员变量. 友元函数的好处: 1.实现类之间的数据共享 2.提高程序运行效率,方便编程 友元函数的坏处: 1.破坏数据的隐蔽性和类的封装性 2.降低了程序的可维护性 所有,友元函数应当谨慎的去使用它. 实例: #include <iostream> #include <cstring> using namespace std ; class Student { private :

  • C++ 中友元函数与友元类详解

    C++ 中友元函数与友元类详解 总的来说,友元分为两类:友元函数与友元类.友元是针对类而言,它提供了一种非类的成员函数来访问类的非公有成员的一种机制.可以把一个函数指定为某类的友元,这个函数称为这个类的友元函数.也可以将类A指定为类B的友元,则类A是类B的友元类,类A的所有成员函数均是类B的友元函数,均可以访问类B的非公有成员.        友元函数的注意事项: (1)友元函数不是类的成员函数,在函数体中访问对象的成员,必须用"对象名.对象成员"方式来访问, 友元函数可以访问类中的所

  • C++友元函数与拷贝构造函数详解

    一.友元函数 1.友元函数概述: (1)友元函数是定义在一个类外的普通函数. 友元函数和普通函数的定义一样;在类内必须将该普通函数声明为友元. (2)友元函数不是成员函数. 不能通过对象来调用,而是直接调用;友元函数可以访问类的公有.受保护以及私有成员,但是必须通过对象.对象指针或者对象引用来访问. 2.友元函数的声明: friend 返回值类型 函数名(参数表); 在类中只需要将这个声明放置在公有部分即可. class Point { double x, y; public: Point(){

  • 简要介绍C++编程中的友元函数和友元类

    一个类中可以有 public.protected.private 三种属性的成员,通过对象可以访问 public 成员,只有本类中的函数可以访问本类的 private 成员.现在,我们来补充介绍一个例外--友元(friend). fnend 的意思是朋友,或者说是好友,与好友的关系显然要比一般人亲密一些.有的家庭可能会这样处理:客厅对所有来客开放,而卧室除了本家庭的成员可以进人以外,还允许好朋友进入.在C++中,这种关系以关键宇 friend 声明,中文多译为友元.友元可以访问与其有好友关系的类

  • Python中enumerate函数代码解析

    enumerate函数用于遍历序列中的元素以及它们的下标. enumerate函数说明: 函数原型:enumerate(sequence, [start=0]) 功能:将可循环序列sequence以start开始分别列出序列数据和数据下标 即对一个可遍历的数据对象(如列表.元组或字符串),enumerate会将该数据对象组合为一个索引序列,同时列出数据和数据下标. 举例说明: 存在一个sequence,对其使用enumerate将会得到如下结果: start        sequence[0]

  • C++简单又轻松的讲解类和对象中友元函数

    目录 友元 浅解概念 友元目的 友元的三种实现 全局函数做友元 类做友元 成员函数做友元 注意事项 总结 友元 用到关键字 friend 浅解概念 举一个非常实际的例子,假如端午节到了你煮了两种粽子,一种是普通的糯米粽子,一种是特殊的五花肉粽子,糯米粽只要是客人都可以品尝,而五花肉棕只限好朋友品尝,这时候就可以用到友元的知识了.在程序里,有些私有属性也想让类外特殊的一些函数或者类访问,就要用到友元函数. 友元目的 让一个函数或者类,访问另一个类的私有属性 友元的三种实现 全局函数.成员函数.类都

  • C++中 Sort函数详细解析

    目录 前言 一.sort函数调用的两种方式 二.sort函数使用场景 三.sort函数排序原理 四.sort函数使用案例 1.升序排列 2.降序排列 实现方式1 实现方式2 3.结构体排序(自定义比较函数) 五.自定义comp函数返回true或false作用 前言 sort函数是algorithm库下的一个函数,sort函数是不稳定的,即大小相同的元素在排序后相对顺序可能发生改变,如果某些场景需要保持相同元素间的相对顺序,可使用stable_sort函数,这里不过多介绍. 一.sort函数调用的

  • C++中友元函数(friend)解析

     文章转自公众号:Coder梁(ID:Coder_LT) 我们知道C++控制对象的私有部分的访问,只能通过公共的接口.这样的设计当然没错,但有的时候也会显得过于严格,产生一些问题. 因此C++提供了另外一种形式的访问权限,叫做友元(friend). 友元有三种,分别是友元函数.友元类和友元成员函数. 通过让函数成为类的友元,可以赋予该函数与类成员函数一样的访问权限,也就是说我们可以在友元函数当中访问类的私有成员变量. 在介绍友元函数的使用之前,我们需要先了解为什么需要友元函数.C++ Prime

  • python中set()函数简介及实例解析

    set函数也是python内置函数的其中一个,属于比较基础的函数.其具体介绍和使用方法,下面进行介绍. set() 函数创建一个无序不重复元素集,可进行关系测试,删除重复数据,还可以计算交集.差集.并集等. set,接收一个list作为参数 list1=[1,2,3,4] s=set(list1) print(s) #逐个遍历 for i in s: print(i) 输出: set([1, 2, 3, 4]) 1 2 3 4 使用add(key)往集合中添加元素,重复的元素自动过滤 list1

  • 解析C++中不能重载为友元函数的四个运算符

    C++规定有四个运算符 =, ->, [], ()不可以是全局域中的重载(即不能重载为友员函数),这是为什么呢?现在先说说赋值运算符"="的重载C++规定赋值运算符"="只能重载为类的非静态成员函数,而不可以重载为类的友元函数.不能重载为类的静态成员应该比较容易理解,因为静态成员函数是属于整个类的,不是属于某个对象的,它只能去操作类静态数据成员.而赋值运算符"="是基于对象操作的.那么为什么赋值运算符不可以重载为类的友元函数?像同样都是双目

  • Sql Server中Substring函数的用法实例解析

    SQL 中的 substring 函数是用来抓出一个栏位资料中的其中一部分.这个函数的名称在不同的资料库中不完全一样: MySQL: SUBSTR( ), SUBSTRING( ) Oracle: SUBSTR( ) SQL Server: SUBSTRING( ) SQL 中的 substring 函数是用来截取一个栏位资料中的其中一部分. 例如,我们需要将字符串'abdcsef'中的'abd'给提取出来,则可用substring 来实现: select substring('abdcsef'

  • c++友元函数与友元类的深入解析

    友元函数和友元类的需要:类具有封装和信息隐藏的特性.只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的.非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性.另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运行效率. 为了解决上述问题,提出一种使用友元的方案.友元是一种定义在类外部的普通函数,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面

随机推荐