friend是C++中封装的漏网之鱼。

C++中的friend同意其它的类或者是函数訪问本类的不论什么成员。甚至是private成员,仅仅要该类声明其为友元。

但是,在有些情况下,并非同意外界訪问类的内部实现而使用友元

这就是在 “模板定义” 与 “隐式类型转换” 之间的一个trick了。

首先,看一个简单的有理数的模板类。该类定义了有理数,而且实现有理数的乘法。

注:下述代码中,将operator*声明为非成员函数。是由于

“假设你须要对成员函数全部的參数(全部的,当然也就包含this指针啦)进行类型转换。那么将该函数声明为非成员函数”。

也就是说,仅仅有当參数位于參数列的时候,这个參数才是隐式类型装换的合格參与者。


updated:这里的參数列指的就是函数的形參列表!!!

可是类的成员函数的那个隐式參数(即this指针)不是隐式转换的合格參与者!。。

这对C++模板类相同适用。

在上述代码中。重载了 * 符号。用于计算两个有理数之间的乘法。

一个自然而然的道理,假设我们须要支持 有理数 * 自然数 ,这是一个无可厚非的要求。当我们才有以下的调用

Rational<int> a = Rational(1,2);

Rational<int> ret = a * 2;

在非模板类中。该函数会将2进行隐式类型转换为Rational对象。再进行乘积运算。

糟糕!编译不通过。在非模板类中这是非常正常的事,但是在模板类中却出现了问题.

简言之。编译器陷入了“纠结”的境界!!

。。

以下一一进行分析:

当编译器看到operator*的调用的时候。编译器不知道我们想要调用什么函数,由于编译器看到这个模板函数时。第一要做的就是将函数实例化出来,也就是要首先判断出T的类型可是几经周折。发现不行。

首先。为了推导出T, 编译器对 * 调用的两个參数进行入手,分别为 Rational<int>   和 int, 由第一个參数能够非常easy的知道得到 T 为int。 可是在第二个实參呢,编译器怎么判断 T 的类型?? 你或许会说,此时编译器就应该使用 Rational<int> 的隐式构造函数 啊。

不就能够 推导出 T 的类型了吗。

可是。编译器绝不会这么做,由于在 模板实參 的推导过程其中是不会 考虑隐式转换的

这是本文最重要的一句话。

因此,在面对这种实參推导 的问题是,friend 便出场了,因为 friend 能够在  模板类 中指明某个特定的函数。也就是说。在函数调用之前。声明该函数。那么在函数调用时,对应的类模板 就不再须要 依赖于 模板实參的推导了,而仅仅须要对这个友元函数进行參数推导就可以。


因此将operator * 声明为该类的友元之后。编译器的行为便不一样了。

类模板并不依赖于实參的推导(此时operator*函数仅仅是该类的一个模板友元函数)。由于此时的实參推导仅仅施行于该友元模板函数身上,所以编译器总是可以在Rational类实例化的时候得知T。

最最核心的一段话:

在onehalf 对象被定义的时候,Rational函数就被实例化了,对应的,它的友元函数  operator* 也就被实例化出来了,也就是说,此时的operator * 不再是一个模板函数了,那么 onehalf  *  2 的时候,便是调用这个已经被实例化的函数了。于是乎。隐式类型转换便能够使用与參数推导了。

可是。另一个问题,便是链接时的问题了,此时,编译器知道我们要调用的是哪个函数了,可是如今那个函数仅仅是被声明在Rational类中,并没有实现它。 假设我们在Rational外部定义该函数,这是行不通的。

因此,仅仅在类定义体中声明该函数,假设不定义的话,连接器便会发出抱怨,找不到定义体。

(updated:这里该函数的定义必须由类定义负责,否则该函数就必须是如今类的外面,那么自然而然该函数就必须得是模板函数,那么參数推导又不起作用了。!!

因此必须定义在函数的内部。!!)

因此,将 operator* 声明为友元函数而且将实现定义在类中。

于是,正确的Rational模板类的定义为:

执行结果为:

大功告成!!

上述代码成功的实现了我们的功能!。!

于是,在类模板定义时。出现了相同的话,假设  在编写一个类模板的时候,而 该类的与模板相关的函数  须要支持函数參数

隐式转换的时候,将该函数定义为模板类类中的friend函数。

updated:模板函数对于參数的类型推导是绝对不会考虑 “构造函数的隐式类型转换的”!

这与一般的函数调用是不一样的。因此我们假设须要对函数的參数进行类型推导,那么就须要将该函数定义为非模板类型,这是编译器就会陷入两难的境界:

然而。对于一般的函数(非模板函数)。编译器是会进行參数推导的(包含调用non-explicit构造函数)!

。!

1在參数推导时使用隐式转换  2 为了让这个函数被具现化,我们又须要将它声明在模板类的内部!

friend!

!!!将函数的声明与定义均置于类内部。

转载于:https://www.cnblogs.com/mengfanrong/p/5140519.html

friend keyword 对于模板 并不只不过友元!!!相关推荐

  1. C++知识点61——typename与class、模板编程与继承、模板类和友元、类模板与static成员

    一.typename与class的异同 1.啥时候既可以使用typename,又可以使用class? 当表示模板参数的时候,二者没有区别 2.啥时候只能使用typename,不能使用class? 当模 ...

  2. 类模板,多种类型的类模板,自定义类模板,类模板的默认类型,数组的模板实现,友元和类模板,友元函数,类模板与静态变量,类模板与普通类之间互相继承,类模板作为模板参数,类嵌套,类模板嵌套,类包装器

     1.第一个最简单的类模板案例 #include "mainwindow.h" #include <QApplication> #include <QPush ...

  3. C++ 将模板申明为友元

    代码编译运行环境:VS2017+Debug+Win32 严格来说,函数模板(类模板)是不能作为一个类的友元的,就像类模板之间不能发生继承关系一样.只有当函数模板(或类模板)被实例化之后生成模板函数(或 ...

  4. 【C++】模板类的友元函数

    模板类友元函数 模板类的友元函数 参考:https://blog.csdn.net/dreamer_lhs/article/details/53580088 区分:友元是否为函数模板 非模板友元 约束 ...

  5. 当类模板遇到了友元函数

    在我学习数据结构的时候,选用了<数据结构(用面向对象方法与C++语言描述)>殷人昆 编著 这本教材.这本书代码较老有一些错误,好多是无法直接在新版本编译器下实现的. 当时我C++模板学的不 ...

  6. C++ 模板类和友元

    模板类的友元分三类: 1,非模板友元. 2,约束模板友元,即友元的类型取决于类被实例化时的类型. 3,非约束模板友元,即友元的所有具体化都是类的每一个具体化的友元. 1,模板类的非模板友元函数 cou ...

  7. 类模板中的友元,友元类

    一:让类模板的某个实例成为友元. #include <iostream> #include <vector> #include <list> using names ...

  8. C++中模板类使用友元模板函数 和友员非模版函数!使用不当出现编译错误:无法解析的外部符号…

    在c++海大本科课程设计的最后章节(模板使用 )中涉及到了在Mat类模板中定义友元函数friend Mat<T> operator+(Mat<T> &m, T num) ...

  9. C++ - 类模板(class template)友元(friend) 的 全部六种形式 及 代码

    类模板(class template)友元(friend) 的 全部六种形式 及 代码 版权所有, 禁止转载, 如有需要, 请站内联系; 本文地址: http://blog.csdn.net/caro ...

最新文章

  1. android h5状态栏消息,安卓实现系统状态栏的隐藏和显示
  2. eclipse没有dynamic web project_Microsoft Teams迎来Project与Roadmap功能集成
  3. [蓝桥杯2018初赛]乘积尾零-数论
  4. oracle中 trunc(),round(),ceil(),floor的使用
  5. C# 依赖注入那些事儿
  6. mysql视图存储_Mysql 视图、存储过程以及权限控制
  7. oracle 拼接_老品牌福建泉州49寸液晶拼接屏多少钱品质
  8. 【图论】Spfa算法求最短路(长得像Dijkstra的,Bellman_Ford的优化算法)
  9. EMOS1.6下的php支持GD库
  10. GPU并行运算与CUDA编程--基础篇
  11. 图文详解如何从win8/8.1中文版(核心版)升级到win8/8.1专业版
  12. Windows 上路由、端口转发配置
  13. 微信小程序,Python爬虫抓包采集实战,采集某成考题库小程序
  14. 罗兰贝格 | 适者生存:VUCA的世界
  15. 无人机停机坪是什么?有哪些作用?无人机自动巡检如何实现?
  16. ps里jpg格式的图怎么保存成透明的
  17. Eclipse平台'Launching test Default' has encountered a problem. Program file not specified解决
  18. imshow 显示图像(Matlab)
  19. ’Hive快速入门课程视频【菜鸟窝出品】
  20. 机器学习入门(七):多项式回归, PolynomialFeatures详解

热门文章

  1. start ssh-agent
  2. android 布局权重问题(最近布局经常坑爹)
  3. [问题记录] cl-api 在 CCL 中生成的文档无内容
  4. Windows 2003 主域控和DNS迁移到Windows 2008 R2(2)
  5. Python倒排索引函数
  6. Leetcode 100. 相同的树 解题思路及C++实现
  7. Spring的单元测试
  8. 判断一个整数是否是水仙花数 || 编写程序,根据输入的月份和年份,求出该月的天数(1-12)|| 运算符的优先级问题 ||输出小写的a-z以及大写的Z—A||求出1-1/2+1/3-1/4…..1/
  9. 机器人视觉——使用numpy进行像素的处理 || 获取图像的属性 || 感兴趣区域ROI || 通道的拆分与合并
  10. freeRtos学习笔(4)消息队列