1、友元1.1 友元产生的背景C 面向的对象编程的三大特征封装 继承 多态其中封装要求将类中属性设置成private私有的属性就不能在类外直接访问了保护了属性的安全性如果类外要求访问类中私有属性需要提供对外的读写接口外部可以通过调接口的方式访问到类中的私有属性。可是如果类外需要频繁访问类中私有属性的话我们改怎么办呢方法一如果频繁访问接口我们就频繁调用接口可是调接口就是调函数函数调用需要经历函数传参、类型比较、安全检测、内存分配.....等一系写操作非常消耗性能如果频繁调用系统性能就会降低显然这不是一个好的选择。方法二使用友元只要在类的内部使用friend关键字进行友元说明就可以无需调接口直接访问类内私有成员这样可以提高效率。但是友元在一定程度上有破坏了类的封装性所有友元要慎用。使用友元的相关注意点友元不是类的成员却可以直接访问类中私有成员提高了运行效率友元破坏了类的封装性要慎用友元的实现方式有三种友元函数友元类友元成员函数1.2 友元函数友元函数是友元使用最多的一种实现方式。概念类外一个普通函数想要访问某一个对象所属类的私有属性直接访问不行调接口访问太麻烦(消耗性能)那就成为这个类的友元即可则该函数就叫做这个类的友元函数。相关注意点友元函数需要在类的内部使用friend关键字进行友元说明,说明的位置可以是类中任意位置不受权限修饰符的限制。友元函数不是类的成员函数没有this指针但可以访问类中的任何成员友元函数的参数类型一般是对象的引用例如Test t理论上友元函数可以同时访问多个类的私有成员只要在每个类中有友元说明。#include iostream using namespace std; class Test{ private: int num; public: Test(int num) :num(num) { } //show int show(void) const { return this-num; } //num读接口 int get_num(void) const { return this-num; } //类内声明友元函数 使用friend friend void func(Test t); }; //普通函数 void func(Test t) { cout t.num endl; } int main() { Test t1(90); func(t1); return 0; }1.3 友元类概念一个类B,想访问另一个类A中的私有成员只需要将类B在类A中进行友元说明类B就可以访问类A的所有成员此时类B叫做类A的友元类。相关注意点友元关系是单向的不具有交换性(你是我的朋友不代表我一定是你的朋友)友元关系不具有传递性(朋友的朋友不是我的朋友)友元关系不能被继承(爸爸的朋友不是我的朋友)#include iostream using namespace std; /*友元类 当一个类B想访问另一个类A中的私有成员需要在类A中声明友元类 注意 (1)友元关系是单向的不具有交换性(你是我的朋友不代表我一定是你的朋友) (2)友元不具有传递性 (朋友的朋友不是我的朋友) (3)友元不能继承 (爸爸的朋友不是我的朋友) */ class A{ private: int a; public: A(int a) { this-a a; } //a读接口 int get_a(void) const { return a; } //友元类的说明 friend class B; }; class B{ public: void func(A t) { cout t.a endl; } }; int main() { A obj1(80); B obj2; obj2.func(obj1); return 0; }1.4 友元成员函数概念类B中的一个成员函数想访问另一个类A中的私有成员需要在类A中进行友元说明说明类B中的这个成员函数是类A的友元成员函数#include iostream using namespace std; //友元成员函数 //类B中的一个成员函数想访问另一个类A中的私有成员需要在把该成员函数在类A中声明为友元成员函数 class A; class B{ public: //类内成员需要类内声明 类外定义 void fun(A p); }; class A{ private: int num; public: A(int num) :num(num) { } //友元成员函数的声明 friend void B::fun(A p); }; //类外定义B类中的成员函数 void B::fun(A p) { cout p.num endl; } int main() { A test1(800); B test2; test2.fun(test1); return 0; }
阅读完成 · 觉得有帮助?