从上一篇博客可以知道,类可以通过访问说明符来控制类里面的成员是否能够被外部成员访问。
public:访问说明符表示其之后的成员可以被类的外部成员访问,也就是可以被整个程序访问。
private:访问说明符表示其之后的成员只能被类里面的成员函数访问,但是外部的成员是不能访问的。
一、友元的介绍
有的时候我们想访问类里面的private成员,同时又不希望它成为类的成员函数,这个时候我们只需要把这个函数作为一个类的友元函数就行。只要在类里面用关键字friend声明一下。
来看一个例子:
class Test { public: Test(); //无参的构造函数 Test(int a, int b);//带两个参数的构造函数 void pirntT(); //类的成员函数 private: int m_a; int m_b; //以下是友元的声明 friend void get(Test &t); }; void get(Test &t) { cout << t.m_a << endl; }
这样我们是可以通过get()函数来访问Test 类中的private成员m_a的。(完整的代码会在最后贴出)
二、友元函数的参数问题
有这样几种情况,根据不同的情况,友元函数的参数可以选择不用将类对象作为参数。
1、如果访问的是非static成员,那么就需要使用本类对象作为成员参数
2、如果访问的是全局变量或者是static变量,就不需要使用本类对象作为成员参数
以上的例子我们就是访问的非static成员,所以我们需要使用类对象作为友元函数的形参。
三、将一个类作为另外一个类的友元
和友元函数一样,如果我们想通过一个类去访问另外一个类的成员,可以将该类声明称另外一个类的友元。
看个例子。
class Test { public: Test(); //无参的构造函数 Test(int a, int b);//带两个参数的构造函数 void pirntT(); //类的成员函数 private: int m_a; int m_b; //以下是友元的声明 friend void get(Test &t); friend class Example; //将Example声明为Test的友元类。 }; class Example { public: void print( Test& p); Example();//无参的构造函数 private: int m_c; int m_d; };上面的例子就是将example类声明为test类的友元类,然后我们就可以通过example的成员函数来访问test类的成员了。
【注意】:友元不具有传递性,假如A是B的友元,B是C的友元,A不是C的友元!A不能访问C里面的成员。
四、友元的优缺点
优点:用友元可以实现信息的共享,提高了效率。
缺点:友元打破了类的访问机制,使用了友元可以轻易修改类里面的变量,这是比较危险的一点。
建议:如果不是特殊情况,尽量不要使用友元,但是当我们在使用运算符重载的时候,有的运算符重载就必须使用友元。
本篇博客所使用到的代码:
#include <iostream> using namespace std; class Test { public: Test(); //无参的构造函数 Test(int a, int b);//带两个参数的构造函数 void pirntT(); //类的成员函数 private: int m_a; int m_b; //以下是友元的声明 friend void get(Test &t); friend class Example; //将Example声明为Test的友元类。 }; class Example { public: void print( Test& p); Example();//无参的构造函数 private: int m_c; int m_d; }; void get(Test &t) { cout << "Test的友元函数get" << endl; cout << t.m_a << endl; cout << "友元函数结束" << endl << endl; } //以下是Test的成员函数的定义 Test::Test() { m_a = 0; m_b = 0; } Test::Test(int a, int b) { m_a = a; m_b = b; } void Test::pirntT() { cout << "Test类里面的printT函数" << endl; cout << "m_a = " << m_a << endl; cout << "m_b = " << m_b << endl; cout << "printT结束" << endl << endl; } //以下是Example类的成员函数的定义 Example::Example() { m_c = 0; m_d = 0; } void Example::print(Test& p) { cout << "Example的成员函数" << endl; cout << p.m_a << endl; cout << "print结束" << endl << endl; } int main() { Test t1(3, 5); get(t1); Example e; e.print(t1); system("pause"); return 0; }