因为后续准备入职的公司都希望能转C++,所以最近也是按部就班的开始进行C++的学习。然后这个系列的文章打算探究C++的语言特性,也比较一下不同语言(如Java,Scala,Python,Go)之间的设计哲学,同时也抛砖引玉的希望能有大拿们的指点。最近在学习过程之中接触了友元函数与友元类的概念,第一篇文章我们就聊聊友元的概念。
1.友元函数:开篇先简单介绍一下友元这个概念吧。
在C++之中,类的友元函数是定义在类外部,但它有权访问类的所有私有(private)成员和保护(protected)成员。尽管友元函数的原型有在类的定义中出现过,但是友元函数并不是成员函数。友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。
直接上个代码,我们看看友元函数与友元类具体是怎么样使用的:
#include <iostream> using namespace std; class Box { public: Box(double l, double b, double h) { length = l; breadth = b; height = h; } friend class A; friend voidboxPrintBox(Box &box); private: double length; double breadth; double height; }; //友元函数,友元函数并非成员函数 voidboxPrintBox(Box &b) { cout << b.height << " " << b.length << " " << b.breadth << endl; } //友元类 class A { public: voidprintBox(Box &b) { cout << b.height << " " << b.length << " " << b.breadth << endl; } }; intmain() { Box box(1,2,3); //友元函数,可以访问Box类的private的变量 boxPrintBox(box); //友元类,同样可以访问Box类的private的变量 A a; a.printBox(box); return 0; }
上面的代码可以看出,友元函数和友元类都可以直接访问到对象的私有变量。接下来我们来分析一下友元函数的特点。
1、为什么要引入友元函数:
在实现类之间数据共享时,减少系统开销,提高效率。具体来说:为了使其他类的成员函数直接访问该类的私有变量。即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数。能够提高效率,表达简单、清晰
2、什么时候使用友元函数:
1)运算符重载的某些场合需要使用友元。
2)两个类要共享数据的时候
3、友元方式的缺点:
1)友元函数破环了封装机制,除非不得已的情况下才使用友元函数。
接下来我们聊聊怎么从面向对象的角度去理解友元关系。(以下内容皆为个人理解,有不准确之处望能斧正)
1)友元函数
友元函数是不从属与类的函数,除了能够访问类的私有变量之外,与其他实现在类外部的函数无异。从面向对象的角度看,函数是不应该独立实现于类之外的。显然独立与类之外的友元函数,从面向对象的角度来思考,是不优雅的解决方式。
这和C++本身兼容C语法有关,如操作符<<的重载利用的就是友元函数。<<的函数重载如下,这个函数是独立与类之外实现的方法:
friend ostream &operator<<(ostream &output, const object &o)
显然,这个<<的函数方法更应该从属在ostream这个类之中,做为一个可重载的方法实现。如下定义