c++友元函数一些见解

1、为什么要引入友元函数:在实现类之间数据共享时,减少系统开销,提高效率
具体来说:为了使其他类的成员函数直接访问该类的私有变量

  即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数优点:能够提高效率,表达简单、清晰缺点:友元函数破环了封装机制,尽量不使用成员函数,除非不得已的情况下才使用友元函数。

2、什么时候使用友元函数:

  1)运算符重载的某些场合需要使用友元。2)两个类要共享数据的时候

3、怎么使用友元函数:

友元函数的参数:

   因为友元函数没有this指针,则参数要有三种情况:1、  要访问非static成员时,需要对象做参数;--常用(友元函数常含有参数)2、  要访问static成员或全局变量时,则不需要对象做参数3、  如果做参数的对象是全局对象,则不需要对象做参数

友元函数的位置:

   因为友元函数是类外的函数,所以它的声明可以放在类的私有段或公有段且没有区别。

友元函数的调用:

   可以直接调用友元函数,不需要通过对象或指针
  • 普通的友元函数
#include<iostream>using namespace std;class Date
{friend ostream& operator<<(ostream& _cout, const Date& d);
public:Date(int year, int mouth, int day):_year(year), _mouth(mouth), _day(day){}
private:int _year;int _mouth;int _day;
};ostream& operator<<(ostream& _cout, const Date& d)
{_cout << d._year << ":" << d._mouth << ":" << d._day << endl;return _cout;
}int main()
{Date d(2018, 11, 2);cout << d << endl;return 0;
}
  • 上面的代码我重载了 << 运算符。这里必须放在类外来定义,如果放在类中来定义的话,我的主函数中 cout<< d<< endl 只能这样写了:d<<cout<<endl;
  • 为什么呢?来看看下面代码。
  • 我的定义写在类中,那么会出现什么情况呢?操作符 << 只需要传两个参数,那么在类中这样定义就会传了三个参数,不要this 指针哦。有人说,那不传 ostream& _cout 不就好了,啊哈,行啊,那么第一个参数就是const Date& d。最后调用的就要是 d<<cout;这样子了。所以友元函数是必须的。
class Date
{ostream& operator<<(ostream& _cout, const Date& d){_cout << d._year << ":" << d._mouth << ":" << d._day << endl;return _cout;}
public:Date(int year, int mouth, int day):_year(year), _mouth(mouth), _day(day){}
private:int _year;int _mouth;int _day;
};

总结:友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。

问题1:友元函数能不能用const修饰?

回答:不能,在类中,const 修饰函数是修饰函数的什么?当然是类函数中的this指针了,那么友元函数有没有this指针呢?当然没有this指针了,所以友元函数不能用const修饰。

友元函数可访问类的私有成员,是不是类的成员函数?

回答:不是,可以这样理解,友元函数是类的好朋友,那么类中的私有成员我允许我的朋友来访问。

友元函数需要放在类的那里来声明呢?public?private?还是?

回答:友元函数可以在类定义的任何地方声明,不受类访问限定符限制

函数A是类A的友元函数,那么函数还能是类B 的友元函数呢?

回答:你肯定不止一个朋友吧。一个函数可以是多个类的友元函数。

除了友元函数,还有友元类。

c++.h

#include<iostream>using namespace std;class Date
{friend class Time;
public:Date(int,int,int);void Print();
private:int _year;int _mouth;int _day;
};class Time
{friend class Date;
public:Time(int ,int ,int);void Print();
private:int _hour;int _minut;int _second;
};

c++.cpp

#include<iostream>
#include"c++.h"
using namespace std;Date::Date(int year = 1990, int mouth = 1, int day = 1):_year(year), _mouth(mouth), _day(day){}void Date::Print(){Time t(11,101,10);cout << _year << "-" << _mouth << "-" << _day << t._hour << "-" << t._minut << "-" << t._second << endl;}Time::Time(int hour = 11, int minut = 10, int second = 10):_hour(hour), _minut(minut), _second(second){}void Time::Print(){Date d(100, 101, 102);cout << d._year << "-" << d._mouth << "-" << d._day << _hour << "-" << _minut << "-" << _second << endl;}void Func()
{Date d(100,101,102);d.Print();Time t(10,11,12);t.Print();}int main()
{Func();return 0;
}
  • 这个要看清楚友元函数必须要在头文件中声明,在另一个文件中来定义。为什么?你自己放在一个文件中你就知道了,我说不清楚。
  • 上面的例子是个友元类,友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

注意:

  • 友元的优缺点
  • 优点:提高了程序运行效率
  • 缺点:破坏了类的封装性和隐藏性
  • 友元关系是单向的,不具有交换性。
  • 比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time 类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。
  • 友元关系不能传递 如果B是A的友元,C是B的友元,则不能说明C时A的友元。

c++之友元函数和友元类相关推荐

  1. C++ 笔记(30)— 友元函数与友元类

    我们知道类的私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接口(成员函数)间接地进行.这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的麻烦. ...

  2. C++友元函数和友元类(C++ friend)详解

    在看VISP视觉库的时候遇到友元函数: Friends void swap (vpDetectorAprilTag &o1, vpDetectorAprilTag &o2) 在定义一个 ...

  3. 模板类中使用友元函数的方式,派生类友元函数对基类的成员使用情况

    在一般友元函数的前面加上 template<typename T),注意在函数的声明和定义处都要加这个模板 例如: //模板类,长方体类 template <typename Elemen ...

  4. c++友元函数与友元类

    友元函数和友元类的需要: 类具有封装和信息隐藏的特性.只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的.非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这 ...

  5. C++友元函数和友元类(一)

    在 C++ 中,一个类中可以有 public.protected.private 三种属性的成员,通过对象可以访问 public 成员,只有本类中的函数可以访问本类的 private 成员.现在,我们 ...

  6. friend之友元函数和友元类

    // friend_func.cpp : Defines the entry point for the console application. 写一个函数求两个点的中点 //友元函数可以访问类的私 ...

  7. C++语言基础(15)-友元函数和友元类

    一个类中可以有 public.protected.private 三种属性的成员,通过对象可以访问 public 成员,只有本类中的函数可以访问本类的 private 成员.现在,我们来介绍一种例外情 ...

  8. C++ 友元(友元函数和友元类)

    友元的作用:提高了程序的运行效率(使得普通函数可以直接访问类的保护数据,避免了类成员函数的频繁调用,即减少了类型检查和安全性检查等都需要时间开销),但它破坏了类的封装性和隐藏性,使得非成员函数可以访问 ...

  9. C++:友元(非成员友元函数、成员友元函数、友元类)

    3.8  友元:友元函数和友元类 友元函数 :既可以是不属于任何类的非成员函数,也可以是另一个类的成员函数,统称为友元函数.友元函数不是当前类的成员函数,而是独立于类的外部函数,但它可以访问该类所有的 ...

  10. c++远征之模板篇——友元函数、友元类

    以下内容源于慕课网的学习整理,如有侵权,请告知删除. 一.友元函数 1.分类 全局函数-->友元全局函数 成员函数-->友元成员函数 2.关键字friend 友元全局函数 如下,利用fri ...

最新文章

  1. 浪潮、寒武纪联手,目标:新基建智算中心
  2. 百度人脸检测与识别项目资源
  3. C++读写局域网共享
  4. 华为魔术手机拆机图解_【连载二十二】手机维修电路基础卡电路
  5. 浅谈域名发散与域名收敛
  6. vue如何新建一个项目(超详细哦--转)
  7. cmd编译java文件中文乱码_乱码 HelloWorld 世界你好 cmd 执行输出的中文java 显示乱码 解决 另附 win无法执行编译运行javac java编译文件的解决方案...
  8. elasticsearch基本查询二(英文分词)term和terms查询
  9. Bootstrap Wizard 多步表单控件
  10. Xcode6无法安装VVDocumenter插件的解决方法
  11. janusgraph 引入 java,janusgraph 默认server使用手记
  12. db2从文件读到数据库
  13. 65个最常见的面试问题与技巧性答复(面试技巧和注意事项),很不错,求职之前,多看看
  14. 100个python算法超详细讲解:三色旗
  15. SQL SERVER2000 如何打开.MDF、.LDF文件
  16. Call to undefined function bcadd()
  17. oracle 版本演进,【比较】Oracle不同版本中关于ALTER TABLESPACE的功能演进
  18. mysql导入sas文件夹_SAS建立本地文件夹
  19. 调用ibm mq_在IBM OpenWhisk中提供和调用动作的简便方法
  20. 非递归遍历二叉树 Java

热门文章

  1. 我的世界网易版显示dns服务器错误怎么弄,手机显示DNS异常怎么办
  2. 谷粒商城:15.商城业务 — 商品上架
  3. NVM:使用nvm安装管理node版本
  4. 封装一个FTPClient连接池工具类
  5. 论文笔记_S2D.53_2013-ICCV_单目相机半稠密视觉里程计(VO)
  6. 汇总|实时性语义分割算法(共24篇)
  7. leetcode之前K个高频元素
  8. HOG特征提取算法解析
  9. VDO-SLAM 配置 2022 Ubuntu20.04
  10. Windows系统服务器中安装Redis服务