C++友元函数
叶落秋白 人气:0友元
用到关键字 friend
浅解概念
举一个非常实际的例子,假如端午节到了你煮了两种粽子,一种是普通的糯米粽子,一种是特殊的五花肉粽子,糯米粽只要是客人都可以品尝,而五花肉棕只限好朋友品尝,这时候就可以用到友元的知识了。在程序里,有些私有属性也想让类外特殊的一些函数或者类访问,就要用到友元函数。
友元目的
让一个函数或者类,访问另一个类的私有属性
友元的三种实现
全局函数、成员函数、类都可以做友元。
全局函数做友元
示例:
class Host //东家 { friend void FriendFunc(Host& H); private: string m_Precious; public: string m_Common; Host() :m_Precious("五花肉粽"), m_Common("糯米粽") {} }; void VisitFunc(Host &H) { cout << "你的 客人可以吃到你的:" << H.m_Common << endl; } void FriendFunc(Host &H) { cout << "你的好朋友可以吃到你的:" << H.m_Precious <<"和"<<H.m_Common<< endl; }
运行效果:
普通客人函数没有权限访问Host类的私有属性m_Precious ,而好朋友函数在类中加上friend关键字声明就可以访问类内所有成员属性。最好写到类最上面,这样可以在第一时间告诉编译器该全局函数是该类的友元函数。
类做友元
示例:
class Host //东家 类 { friend class FriendFunc; private: string m_Precious; public: string m_Common; Host() :m_Precious("五花肉粽"), m_Common("糯米粽") {} }; class FriendFunc //好朋友类 { public: Host* host; void visit(); FriendFunc(); }; void FriendFunc::visit() { cout << "你的好朋友可以吃到你的:" << host->m_Precious << "和" << host->m_Common << endl; } FriendFunc::FriendFunc() { host = new Host; } void test01() { FriendFunc F; F.visit(); } int main() { test01(); }
运行效果:
首先直接copy下来全局函数做友元的Host类,然后把上面的FriendFunc函数变为类;同样在Host类中声明FirstFunc类是其友元类,然后给友元类定义Host类指针,vist访问方法和默认构造函数,这里方法和函数均在类内定义,类外声明;注意:构造函数的声明不需要返回值类型。
友元类的构造函数定义中直接new了一个Host类,当我们调用友元类的默认构造同时调用Host的默认构造函数并通过初始化列表完成自动赋值,这样就可以在visit函数中访问Host类的成员属性了。使用指针的原因就是new的返回值为指针类型,在堆区开辟空间。
成员函数做友元
示例:
#include<iostream> using namespace std; class Host; class FriendFun//好朋友类 { public: FriendFun(); Host* host; void visit(); //让其可以访问Host类的私有成员 void visit0(); //和visit对比,不能访问Host类私有成员 }; class Host //东家 类 { friend void FriendFun::visit(); private: string m_Precious; public: string m_Common; Host() :m_Precious("五花肉粽"), m_Common("糯米粽") {} }; FriendFun::FriendFun() { host = new Host; } void FriendFun::visit() //让其可以访问Host类的私有成员 { cout << "你的好朋友可以吃到你的:" << host->m_Precious << "和" << host->m_Common << endl; } void FriendFun::visit0() //和visit对比,不能访问Host类私有成员 { cout << "你的好朋友可以吃到你的:" << host->m_Common << endl; } void test() { FriendFun F; F.visit(); F.visit0(); } int main() { test(); }
运行效果:
成员函数作为友元和全局函数作为友元区别就是函数声明的位置不同,同样在Host类里加上friend关键字即可,但是一定要注意函数或者方法声明后定义的位置,死死记住代码是按照顺序执行的。
注意事项
举个例子:如果直接类内定义FriendFun的构造函数,程序会提示你未定义类型Host,为什么呢,我明明在Host类之前声明了啊,确实声明了,也定义了啊,但是编译器来不及看到定义就以及执行了new Host,肯定会报错;按正确的写法就是把构造函数定义写在Host定义之后,这样程序就把定义的Host看完了,就可以自然而然的生成新的成员了;其实visit的定义也必须写在调用FriendFun构造函数之后,因为只有构造生成了新成员,才能访问到公共或者私有属性啊!
总结
学习完这篇快点去定义谁才能获取你五花肉粽子的特权吧,挺有意思的。总体来说友元这块知识不难,但是一定要注意细节,我在总结这里再说一次,代码一定是按照顺序执行的,类内外定义一定要注意顺序,还记得这段知识点,一个bug卡了我两个小时,希望你们能避开我的坑,顺利前行
加载全部内容