目录

  • 一.友元函数
    • 先看普通函数声明为友元函数:
    • 再看类成员函数声明为友元函数:
    • 最后说明
  • 二.友元类
  • 三.完整示例:
  • 四.同一个类(class)的类对象(object)互为友元

友元是什么,说白了一句话,就是为了不受类的封装性的约束 ,好让我们可以 访问类私有数据成员。语法上使用friend关键字。

一.友元函数

友元函数可以是普通函数或者类成员函数。

先看普通函数声明为友元函数:

如下所示:

#include <iostream>
#include <cmath>using namespace std;class Point
{//普通函数声明为类的友元函数friend double TwoPointsDistant(const Point& pnt1, const Point& pnt2);
public:Point(double x=0, double y=0):_x(x), _y(y){}double getPointXAxis() const { return this->_x; }double getPointYAxis() const { return this->_y; }
private:double _x;double _y;
};//计算两点的距离
double TwoPointsDistant(const Point& pnt1, const Point& pnt2)
{return sqrt(  pow((pnt1._x - pnt2._x), 2) + pow((pnt1._y - pnt2._y), 2)   );
}int main()
{Point point1(1.1,2.2);Point point2(3.3, 4.4);cout << TwoPointsDistant(point1, point2) << endl;system("pause");return 0;
}

这里说明一点:TwoPointsDistant()函数必须在Point类的定义下面,至于原因,很简单,你若放在Point上面,Point的数据成员_x和_y都没定义呢,你用个锤子。

再看类成员函数声明为友元函数:

还以上面的类为例,现在加一个_PointMove_类,它有一个成员函数_PointAxisAddOne,_作用是将点的坐标都加1。如下:

class PointMove
{public:void PointAxisAddOne(Point& pnt);
};

这里就出现了一个问题:_Point_和_PointMove_哪个放在前面?先给出答案,应该把_PointMove_放在前面,并且是必须的,如下:

class Point;//前向声明Pointclass PointMove
{public:void PointAxisAddOne(Point& pnt);
};class Point
{//普通函数声明为类的友元函数friend double TwoPointsDistant(const Point& pnt1, const Point& pnt2);//类成员函数声明为友元friend void PointMove::PointAxisAddOne(Point& pnt);/*这里同前*/
};//类成员函数的定义
void PointMove::PointAxisAddOne(Point& pnt)
{pnt._x = pnt._x + 1;pnt._y = pnt._y + 1;
}

这里注意,对于类的成员函数,声明为其他类的友元函数时需要加上类的作用域,即指出该函数属于哪个类。如上面的_PointMove::_。

同时,需要说明的是,PointAxisAddOne()函数的定义是必须放在Point类定义后面的,这和普通函数的道理是一样的。

最后说明

  1. 一个函数Func被声明为类A的友元函数,那么是不能直接使用this指针来访问类A的数据成员的(当然,若Func是类B的成员函数,它可以通过this访问类B的数据成员),这和成员函数不同。
  2. 一个函数Func为什么要声明为某个类A的友元,就是因为函数的参数类型为类A类型,我想访问这个类对象的数据成员,所以被声明为类A的友元函数的参数类型必定为类A,如friend Func(A& obj);

二.友元类

若是将一个类C都声明为另一个类A的友元类,则类C中的成员函数均可访问类A中的私有数据成员。如下:

class Point
{//友元类friend class PointInfo;...
}
class PointInfo
{public://打印点所处象限void PrintQuadrant(const Point& pnt) const{if (pnt._x > 0 && pnt._y > 0)cout << "点"<<"(" << pnt._x << "," << pnt._y<<")" <<"处于第一象限" << endl;}
};

当然,你也可以把_PointInfo_写在_Point_前,只是函数_PrintQuadrant()_的定义就不能在类内实现了,只能在_Point_后实现,原因和前面一样,不再赘述。

三.完整示例:

#include <iostream>
#include <cmath>using namespace std;class Point;class PointMove
{public:void PointAxisAddOne(Point& pnt);
};class PointInfo
{public://打印点所处象限void PrintQuadrant(const Point& pnt) const;
};class Point
{friend class PointInfo;friend double TwoPointsDistant(const Point& pnt1, const Point& pnt2);friend void PointMove::PointAxisAddOne(Point& pnt);public:Point(double x=0, double y=0):_x(x), _y(y){}double getPointXAxis() const { return this->_x; }double getPointYAxis() const { return this->_y; }void PrintAxis(const Point& pnt) const{}
private:double _x;double _y;
};//打印点所处象限
void PointInfo::PrintQuadrant(const Point& pnt) const
{if (pnt._x > 0 && pnt._y > 0)cout << "点"<<"(" << pnt._x << "," << pnt._y<<")" <<"处于第一象限" << endl;
}void PointMove::PointAxisAddOne(Point& pnt)
{pnt._x = pnt._x + 1;pnt._y = pnt._y + 1;
}double TwoPointsDistant(const Point& pnt1, const Point& pnt2)
{return sqrt(  pow((pnt1._x - pnt2._x), 2) + pow((pnt1._y - pnt2._y), 2)   );
}int main()
{Point point1(1.1,2.2);Point point2(3.3, 4.4);cout << TwoPointsDistant(point1, point2) << endl;PointInfo pf;pf.PrintQuadrant(point1);system("pause");return 0;
}

VS2015打印结果:

四.同一个类(class)的类对象(object)互为友元

还以上面给出的例子为基础,现在在_Point_类加一个成员函数func(const Point& pnt),它返回点的x轴和y轴的和。如下所示。

class Point
{/*这里同上*/double func(const Point& pnt){return pnt._x + pnt._y;}
private:double _x;double _y;
};

现在我生成两个对象,并作如下操作:

 Point point1(1.1,2.2);Point point2(3.3, 4.4);cout << point1.func(point2) << endl;

最后的结果是打印出7.7。看到这里不知道你有没有疑问:为什么可以通过point1直接访问point2的私有数据成员,而没有将func()声明为友元函数?侯捷老师是这么解释的:相同class的各个objects之间互为友元。
所以对于一个类A,若有一个成员函数Fun(A& arg),可以通过arg直接访问A的私有数据成员。

C++友元(friend)解释相关推荐

  1. c++学习13 类与对象(二)c++对象模型和this指针和友元

    类和对象 c++对象模型和this指针 成员变量和成员函数分开存储 在c++中类内的成员变量和成员函数分开存储 只有非静态成员变量才属于类的对象 #include<iostream> us ...

  2. 如何正确理解友元(最全解释)

    1.为什么要使用友元:类的主要特点之一是数据的隐蔽和封装,即类的私有成员只能在类定义到范围内使用,也就是说只能通过它的成员函数来访问.但是,有时为了访问类的私有成员而需要在程序中多次调用成员函数,这样 ...

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

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

  4. 友元实例:友元类及友元函数

    学习了c++这么久,一直没有对友元进行了解,据说友元不是特别好用(据说,不是我说的),因此直到今天才去了解.其实友元确实不是很常用,但友元功能确实很实用,它不但能够释放类中的非公有成员,同时还能保证了 ...

  5. 【C++grammar】析构、友元、拷贝构造函数、深浅拷贝

    目录 1.Destructor(析构函数) 在堆和栈(函数作用域与内嵌作用域)上分别创建Employee对象,观察析构函数的行为 2.Friend(友元) 1.为何需要友元 2.友元函数和友元类 3. ...

  6. 使用友元,编译出错fatal error C1001: INTERNAL COMPILER ERROR (compiler file 'msc1.cpp', line 1786) 的解决...

    版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明 http://lihuan-dianxian.blogbus.com/logs/42102230.html 同学拿了个很简单的小程序过 ...

  7. C++友元函数简单示例

    友元函数专业解释:友元函数是可以直接访问类的私有成员的非成员函数. 它是定义在类外的普通函数,它不属于任何类,但需要在类的定义中加以声明,声明时只需在友元的名称前加上关键字friend. 在我看来,友 ...

  8. java有没有友元函数_c++中友元函数理解与使用

    在学习c++这一块,关于友元函数和友元类,感觉还是不好理解,但是井下心来,理解,需要把我一下几点. 首先讲友元函数. (1)友元函数: 1)C++中引入友元函数,是为在该类中提供一个对外(除了他自己意 ...

  9. 友元函数实现复数加减法

    C++程序:友元函数重载复数减法在dev-C++ 5.11下运行没有问题,但是在vc6.0运行时提示错误. (自考C++程序设计2019年版,程序4-1,例4-2.程序4-2等有同样问题) 程序代码如 ...

最新文章

  1. JVM年轻代,老年代,永久代详解​​​​​​​
  2. 读书笔记-《增长黑客》-低成本、高效率的精准营销
  3. 无线AP如何区分来宾(流动)用户和正常用户?
  4. 鹅厂分享:AB实验只是开始?如何归因和解读才是王道!
  5. 【渝粤教育】国家开放大学2018年春季 7218-21T医学伦理学(本) 参考试题
  6. eureka需要替换吗_nacos无缝替换eureka
  7. vue子组件赋值props_vue 父子传值props赋值失效问题
  8. XMPP的简介和基本概念
  9. 1024程序员节持续引爆星城:500万程序员线上线下互动,共迎开源软件、操作系统新时代...
  10. internal/child_process.js:313 Error:spawn EACCES
  11. 最简单的方法实现小程序按钮跳转到指定界面
  12. hadoop-uber作业模式
  13. 水星mw325r设置无线服务器未响应,水星MW325R无线路由器设置教程
  14. python基础练习题:纳特拼音alaphabeta【难度:1级】--景越Python编程实例训练营,不同难度Python习题,适合自学Python的新手进阶
  15. 教你同时分析圆通快递多个单号的物流情况
  16. Unifying Task-oriented Knowledge Graph Learning and Recommendation
  17. 云计算优势与风险并存 安全是首要问题
  18. 线程同步与互斥:互斥锁
  19. 2021-2027全球与中国锂电池三元正极材料市场现状及未来发展趋势
  20. 场效应晶体管有什么特点

热门文章

  1. 小微企业的一账通解决方案(企业账号集成一体化)
  2. 国赛培训——随机化算法——蒙特卡洛模拟
  3. 修笔记本电脑(飞行堡垒)
  4. Burp Suite下载
  5. ObjectARX第一课:创建自定义实体
  6. editplus 注册码
  7. 腾讯大佬总结的人脸表情识别技术
  8. 失去焦点和获得焦点发生事件(js)
  9. 百万级报警平台的架构设计与实现
  10. HTML标签列表(字母排序)