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

 更新时间:2022年01月03日 15:21:57   作者: 梁唐  
这篇文章主要分享了C++友元函数讲解,C++提供了一种形式的访问权限,叫做友元,友元有三种,分别是友元函数、友元类和友元成员函数,下面将详细介绍该内容,需要的小伙伴可以参考一下

 文章转自公众号: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++友元函数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++超详细讲解模板的使用

    C++超详细讲解模板的使用

    这篇文章主要介绍了C++中模板(Template)的详解及其作用介绍,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-06-06
  • C++设计模式编程中的迭代器模式应用解析

    C++设计模式编程中的迭代器模式应用解析

    这篇文章主要介绍了C++设计模式编程中的迭代器模式应用解析,迭代器模式注重对集合中元素的遍历而不使其暴露,需要的朋友可以参考下
    2016-03-03
  • 一文带你了解C++中的右值引用与移动语义

    一文带你了解C++中的右值引用与移动语义

    本篇文章主要为大家详细介绍了C++中的右值引用与移动语义的相关知识,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2023-03-03
  • 利用C语言实现将格式化数据和字符串相互转换

    利用C语言实现将格式化数据和字符串相互转换

    这篇文章主要为大家详细介绍了2个函数,分别是sprintf和sscanf,可以用来实现将格式化数据和字符串相互转换,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-03-03
  • C语言中隐藏结构体的细节

    C语言中隐藏结构体的细节

    以笔者粗浅的认识,有两种最常用的方法,可以实现库内结构体定义的隐藏:接口函数形参使用结构体指针,接口函数形参使用句柄。
    2017-05-05
  • C++虚继承原理与类布局深度分析

    C++虚继承原理与类布局深度分析

    这篇文章主要介绍了C++虚继承原理与类布局分析,本文的目标是探究虚继承的实现方式和类布局(Class Layout)的具体规则,需要的朋友可以参考下
    2024-04-04
  • C++ 类的友元机制解读

    C++ 类的友元机制解读

    这篇文章主要介绍了C++ 类的友元机制的相关资料,帮助大家更好的理解和学习使用c++,感兴趣的朋友可以了解下
    2021-02-02
  • QT网络编程Tcp下C/S架构的即时通信实例

    QT网络编程Tcp下C/S架构的即时通信实例

    下面小编就为大家带来一篇QT网络编程Tcp下C/S架构的即时通信实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • Qt网络编程之TCP通信及常见问题

    Qt网络编程之TCP通信及常见问题

    这篇文章主要为大家详细介绍了Qt网络编程之TCP通信及常见问题,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-08-08
  • C语言中enum关键字的实现示例

    C语言中enum关键字的实现示例

    这篇文章主要介绍了C语言中enum关键字的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-03-03

最新评论