-
谈谈对友元的理解
2020-04-21 21:52:03类的主要特点之一就是数据隐藏,即类的私有成员无法在类的外部访问。...友元函数不是类的成员,不带this指针。 友元函数可访问对象任意成员属性,包括私有属性。 注意的是: 友元关系不能被继承...类的主要特点之一就是数据隐藏,即类的私有成员无法在类的外部访问。但是,有时候需要在类的外部访问类的私有成员。解决方法就是使用友元函数。友元函数是一种特权函数,c++允许这个特权函数访问私有成员。
friend关键字只出现在声明处。
其他类,类成员函数,全局函数都可以声明为友元。
友元函数不是类的成员,不带this指针。
友元函数可访问对象任意成员属性,包括私有属性。
注意的是:
友元关系不能被继承
友元关系是单向的
友元关系不具有传递性 -
【C++】友元的理解和使用
2020-10-25 21:36:29友元函数1.1 如何对`<< 和 >>`进行重载呢?2.友元类 1.友元函数 友元函数可访问类中的所有成员,但不是该类中的成员函数。 例: class Date { friend void Print(Date& d);//友元函数 public: ...先思考一个问题,如何将不属于当前结构的函数访问当前结构中的成员?
在这里就引出了友元这个概念。在当前结构中声明结构外函数为友元函数,则该友元函数就可访问该结构中的所有成员。
友元又分为:友元函数和友元类。
1.友元函数
友元函数可访问类中的所有成员,但不是该类中的成员函数。
例:
class Date { friend void Print(Date& d);//友元函数 public: Date(int year, int month, int day)//构造函数 : _year(year) , _month(month) , _day(day) {} private: int _year; int _month; int _day; }; void Print(Date& d)//外部函数 { cout << d._year << "-" << d._month << "-" << d._day << endl; } void TestClass() { Date d1(2020,10,6); Date d2(2020, 10, 1); Print(d1); }
结果:类外函数可访问类中的成员
1.1 如何对
<< 和 >>
进行重载呢?若在类中对
<<
进行重载:
而将程序改成这样:可正常运行
结果为:
为什么会这样呢?成员函数中,默认的第一个参数为this指针。则this指针需要作为重载符的左操作数。而在上述中,cout作为了左操作数。但这也不符合
<<
本身的定义,所以是不对的。则必须将该函数进行类外声明和实现,但是类外的函数又没办法访问类中成员,这里就要采用友元函数对<<
进行重载。class Date { friend void Print(Date& d);//友元函数 friend void operator<<(ostream& _cout, Date& d); public: Date(int year, int month, int day)//构造函数 : _year(year) , _month(month) , _day(day) {} private: int _year; int _month; int _day; }; void operator<<(ostream& _cout,Date& d) { _cout << d._year << "-" << d._month << "-" << d._day; } void TestClass() { Date d1(2020,10,6); Date d2(2020, 10, 1); cout << d1; }
上述代码可正常运行。、
但运算符重载时,需考虑到,不改变运算符本身的含义。
<<
是可对结果进行连续输出的,所以上述代码无法进行连续输出,因为没有返回值类型。做修改:返回输出流的引用
友元函数需要注意的点:
- 尽量不要用
const
修饰友元函数。在返回值为引用时,就会出错。 - 友元函数可在类中的任何地方声明,不受类的访问限定符限制
- 一个函数可以是多个类的友元函数
2.友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。
例:B类是A类的友元类。
class Time { friend class Date; public: Time(int hour = 20, int mintue = 10, int second = 10) :_hour(hour) , _minute(mintue) , _second(second) {} void Print() { cout << _hour << "-" << _minute << "-" << _second << endl; } private: int _hour; int _minute; int _second; }; class Date { public: Date(int year, int month, int day)//构造函数 : _year(year) , _month(month) , _day(day) {} void SetTime(int hour, int minute, int second) { _t._hour = hour;//调用Time类的成员变量 _t._minute = minute; _t._second = second; } void Print() { _t.Print();//调用Time类的成员函数 } private: int _year; int _month; int _day; Time _t; }; void TestClass() { Date d1(2020,10,6); Date d2(2020, 10, 1); d1.SetTime(21, 13, 5); d1.Print(); }
正常输出结果:
友元类中的注意事项:
- 友元关系是单向的,不具有交换性。B是A的友元,A未在B中friend,则A不是B的友元。
- 友元关系不能传递。B是A的友元,C是B的友元,C不一定是A的友元。
- 尽量不要用
-
对c++友元函数和友元类的理解
2016-06-26 20:44:001,友元函数的定义和作用 我们已知道类具有封装和信息隐藏的特性。只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为...1,友元函数的定义和作用
我们已知道类具有封装和信息隐藏的特性。只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性。另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开销,而影响程序的运行效率。
为了解决上述问题,提出一种使用友元的方案。友元是一种定义在类外部的普通函数,但它需要在类体内进行说明,为了与该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是它可以访问类中的私有成员。友元的作用在于提高程序的运行效率(即减少了类型检查和安全性检查等都需要的时间开销),但是,它破坏了类的封装性和隐藏性,使得非成员函数可以访问类的私有成员。
2,上述的访问不是直接访问,对于普通私有成员变量是通过对象访问,对于私有静态变量是通过类访问。为什么不能直接访问呢?
先了解一下为什么成员函数可以直接访问成员变量?
成员函数能够访问类的成员变量是因为传递了指向当前对象的this指针,它如果访问数据成员对其操作是this指向的对象的数据成员,是有实际意义的 。
友元函数不是成员函数,没有传递隐藏的this指针,只能间接访问。
这点其实和静态成员函数一样,静态成员函数也是没有this指针的,所以它只能访问静态成员变量或者通过对象访问非静态成员变量。
例子:
3,类和类之间的友元关系不能继承。class Rect { public: Rect() // 构造函数,计数器加1 { count++; } //Rect(const Rect& r) //{ // width = r.width; // height = r.height; // count++; //} ~Rect() // 析构函数,计数器减1 { count--; } static int getCount() // 返回计数器的值 { return count; } friend int get(); private: int width; int height; static int count; // 一静态成员做为计数器 }; int Rect::count = 0; // 初始化计数器 int get() { return Rect::count;//友元函数通过类访问私有静态成员变量 } int main() { Rect rect1; cout<<"The count of Rect: "<<Rect::getCount()<<endl;//通过类访问公有静态成员函数,输出1 Rect rect2(rect1); // 使用rect1复制rect2,此时应该有两个对象 cout<<"The count of Rect: "<<Rect::getCount()<<endl; //输出1 cout << get() << endl;//输出1 //cout << Rect::count << endl;//不能编译通过,不能访问私有成员 system("pause"); return 0; }
下边转载自:
http://blog.csdn.net/shandianling/article/details/7469361
C++ Primer中有如下描述:友元关系不能继承。基类的友元对派生类的成员没有特殊访问
权限。如果基类被授予友元关系,则只有基类具有特殊访问权限,该基类的派生类不能访问授予友元关系的类。然而通过实践发现,VS编译器并没有安装上述描述来处理,下面的规则与上述描述相悖,却符合VS编译器的处理规则。
注:有待通过g++编译器来验证。
1 友元类的继承问题
1.1 A类的友元B的派生类C 不能访问A类的private或protect成员变量。但可以通过B提供的接口来访问A。(废话肯定可以)
- #include <iostream>
- using namespace std;
- class B;
- class A
- {
- int a;
- public:
- A(int x=0) { a=x; }
- friend class B;
- };
- class B
- {
- int b;
- public:
- void fun(A& ob){ cout << ob.a << endl;}
- };
- class C:public B
- {
- public:
- //void fun2(A& ob){ cout <<ob.a <<endl;} //派生类新加的函数却不能访问A,此句会报错
- };
- void main()
- {
- A a(55);
- C c;
- c.fun(a); //C是B的派生类 通过基类B的函数fun仍然可以访问
- }
1.2. Base的友元可以通过Base的派生类Drived访问Base的private,protect成员变量,但不能访问Drived的private,protect成员变量。(这一点似乎与《C++ primer》里说的有点冲突)个人理解:Drived的对象本身就包含Base,Base的友元Frnd自然就可以访问Base的部分。
- #include <iostream>
- using namespace std;
- class Base
- {
- int m_a;
- public:
- Base(int x=0){ m_a=x; }
- friend class Frnd;
- };
- class Drived:public Base
- {
- private:
- int m_c;
- public:
- Drived(int x):Base(x){m_c=x;}
- };
- class Frnd
- {
- public:
- void fun(Base& ob) { cout <<ob.m_a << endl; }
- void fun2(Drived& ob)
- {
- cout << ob.m_a<<endl;
- //cout <<ob.m_c<<endl; //编译错误
- }
- };
- int main()
- {
- Drived d(1);
- Frnd f;
- f.fun(d);
- f.fun2(d);
- system("pause");
- return 0;
- }
3 友元类的传递问题
A的友元是B,B的友元是C,那A的友元是C? 不是,友元类不具有传递性。
-
C++工作笔记-对友元函数的进一步理解
2020-09-01 08:43:47友元的特点就是他是普通函数,并不是成员函数。他可以调用这个类的私有成员。 这里有个实际用法: 如上的redisAsyncCommand函数,其中第二个参数为函数指针。 这里不能反成员函数指针。因为成员函数指针里面...这里在GitHub上看redis相关的代码发现的。再次记录下。
友元的特点就是他是普通函数,并不是成员函数。他可以调用这个类的私有成员。
这里有个实际用法:
如上的redisAsyncCommand函数,其中第二个参数为函数指针。
这里不能反成员函数指针。因为成员函数指针里面会带一个类名。
或许通过
QMAKE_CXXFLAGS += -Wno-pmf-conversions
这种方式可以转,但会出现一些问题。
官方推荐用友元去解决:
其中详细如下:
这里可以看到privdata及为传过来的this指针。
-
友元函数
2019-10-01 14:36:53友元函数: 友元函数是一种 1.... 2.... ...即便友元函数的原型出现在类定义中,友元函数并不是成员函数,这一点...所以不要局限对友元的理解。 声明一个类的友元函数,只需要加上友元关键字即可: class Box ... -
在C++中关于友元函数的进一步理解
2020-12-26 08:44:26这里在百科上对友元函数的解释: 友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。类授予它的友元特别的访问权。通常同一个开发者会出于技术和非技术的原因,控制类的友元和成员函数(否则当你想更新... -
在C++中的友元函数进一步理解
2018-03-17 21:02:53这里重新将类的成员函数的定义看一下:百科上的认识:类的成员函数的原型要写在类体中,原型说明了函数的参数表和返回值类型。而函数的定义一般在类外面,也可以直接...这里在百科上对友元函数的解释: 友元函数是... -
C++静态成员和友元成员的理解
2020-04-01 13:43:46对静态成员的理解 在之前的学习过程中我们已经了解到模块数据的共享与保护机制,比如:数据成员对外不公开,对象里定义的变量也具有作用域等等。 对于一个类,函数成员是所有的对象相同的,而数据成员则是各自不同的... -
理解友元 & 递归的reverse
2011-05-30 10:02:00//定义类X、Y、Z,函数h(X *),满足: //类X有私有成员i,Y的成员函数g(X *)是X的友元函数,实现对X的成员i加1, //类Z是类X的友元类,其成员函数f(X *)实现对X的成员i加5, //函数h(X *)是X的友元函数,实现对X的... -
简要介绍C++编程中的友元函数和友元类
2021-01-20 06:13:09一个类中可以有 public、protected、private 三种属性的成员,通过对象可以访问 public 成员,只有本类中的函数可以访问本类的 private 成员。...如果您对友元这个名词不习惯,可以按原文 friend 理解为 -
C++中的友元函数和友元类
2013-01-05 22:12:00百度百科上对友元函数是这样定义的:友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。。类授予它的友元特别的访问权。通常同一个开发者会出于技术和非技术的原因,控制类的友元和成员函数(否则当你想... -
C++友元函数和友元类
2016-07-11 10:01:16百度百科上对友元函数是这样定义的:友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。。类授予它的友元特别的访问权。通常同一个开发者会出于技术和非技术的原因,控制类的友元和成员函数(否则当你想... -
c++ 友元
2014-02-24 16:50:33友元可以理解为是类的“朋友”,它可以访问类的保护和私有成员,即一个类的友元对类的访问不受访问权限的控制。友元的作用在于提高程序的运行效率,但是,它破坏了类的封装性和隐藏性。友元可以是一个函数,该函数被... -
一.C++学习笔记-友元
2016-10-09 16:21:33我对友元的理解很简单:就是在类的内部申明一些"朋友",一般这些"朋友"都有一个参数类型是这个类的类型,这时候这些"朋友"边能够直接使用这个类的私有属性和函数了。 #include "stdafx.h" #include #include using ... -
c++类的友元、类的静态成员
2020-03-29 08:50:39对于友元的一些理解: 类的友元:关键字friend 弊端:使得被该类隐藏的一些数据成员在类的外部也可见,破坏了类的封装性; 好处:在某些特定的场合下可以减少开销,提高程序运行效率。 友元函数:在类的内部声明... -
c++ 友元函数 友元类
2017-04-04 22:50:56结合着类的特性和类中一般成员函数,我们可以这样理解:类具有封装和信息隐藏的特性。只有类的成员函数才能访问类的私有成员,程序中的其他函数是无法访问私有成员的。非成员函数可以访问类中的公有成员,但是如果将... -
C++ 模板友元
2020-01-04 10:23:22文章目录C++ 模板友元1. 模板之间一对一的友元2. 模板的通用友元3. 模板的类型参数成为友元 ...本文记录模板友元的使用方式。 1. 模板之间一对一的友元 这种友元符合这种场景: 存在一个模板类A。 另外存在一个模板... -
c++ 友元函数和友元类
2018-07-05 23:48:00其实,简单理解,友元函数就是类的好朋友,使用friend关键字,这样友元函数就可以访问类的私有和protected成员变量了。Ø 若B类是A类的友员类,则B类的所有成员函数都是A类的友员函数Ø 友员类通常设计为一种对... -
[C++] 友元函数和友元类
2018-12-07 22:48:48c++中对类的访问通过访问修饰符进行控制,类对象不能访问private和protected(子类中可以)修饰...可以将友元理解为“类的好朋友”。简单来说,一个类的友元可以访问其私有属性和方法。 1.2.创建友元函数 Step1.创建... -
☆ C++ 友元函数与友元类
2018-11-10 19:48:29类的存在,简单点可以直接将其理解为对数据的读取权限进行了限制, 虽然安全性有增强,但在处理实际问题的过程中也不免会遇到一些难处: 举个例子【友元函数】: 首先定义一个点类(Point) , 现在如何求两点之间的... -
C++友元函数
2018-08-10 16:09:03C++友元函数的理解 我们知道,C++ 的三大特性之一:封装。 如果我们需要对外部提供一个接口,去访问某个类中的全部成员(不管是public还是private)。则C++的友元函数能够为我们实现。关于友元函数的具体实现我就... -
模板类和友元
2017-03-22 19:02:04懒得抄了,直接截图,后面对模板类友元函数是单个类具体化的友元,还是模板类所有具体化...友元函数与 T有关时,比如包含T的参数等,指定友元的具体化只是对应具体化类的友元,即一对一的关系,指定具体化友元指定访问 -
模板类中包含模板类友元和其他友元函数
2017-05-03 22:02:29发表一点自己对 《C++ Primer 5th》模板那块的理解, 欢迎指正一对一友好关系在类模板与另一个模板(模板类或模板函数)间建立对应实例及其友好关系,为了在类模板中引用另一个类模板或函数的一个特定实例,必须先... -
友元函数分析
2017-12-17 13:43:42友员是一种“权限”,我把A设置为我的friend (权限任意public,private),A就可以在类外对我进行访问; A访问朋友,通过的媒介是 引用 & 。 场景:使其他类的成员函数直接访问该类的私有变量。即:允许外面的类... -
友元关系和继承
2013-12-09 19:57:20(2)基类的友元对派生类的成员没有特殊的访问权限。(3)如果基类北授予友元关系, 则只有基类具有特殊的访问权限,该基类的派生类不能访问授予友元关系的类。 很精炼,就是理解起来有点晦涩。还好作者提供了例子...