{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# C++的友元" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 1. 友元简介" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "① 生活中你的家有客厅(Public),有你的卧室(Private),客厅所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的好闺蜜进去。\n", "\n", "② 在程序里,有些私有属性,也想让类外特殊的一些函数或者类进行访问,就需要用到友元的技术。\n", "\n", "③ 友元的目的就是让一个函数或者类访问另一个类中私有成员。\n", "\n", "④ 友元的关键字为 friend。\n", "\n", "⑤ 友元的三种实现:\n", "\n", "1. 全局函数做友元。\n", "2. 类做友元。\n", "3. 成员函数做友元。" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#include \n", "using namespace std;\n", "\n", "//建筑物类\n", "class Buiding\n", "{\n", " //goodfriend全局函数是Buiding类好朋友,可以访问Buiding中私有成员\n", " friend void goodfriend(Buiding* buiding);\n", "\n", "public:\n", " Buiding() //构造函数 赋初值\n", " {\n", " m_SittingRoom = \"客厅\";\n", " m_BedRoom = \"卧室\";\n", " }\n", "\n", "public:\n", " string m_SittingRoom; //客厅\n", "\n", "private:\n", " string m_BedRoom;\n", "};\n", "\n", "//全局函数\n", "void goodfriend(Buiding *buiding)\n", "{\n", " cout << \"好基友全局函数 正在访问:\" << buiding->m_SittingRoom << endl;\n", " cout << \"好基友全局函数 正在访问:\" << buiding->m_BedRoom << endl;\n", "\n", "}\n", "\n", "void test01()\n", "{\n", " Buiding building;\n", " goodfriend(&building);\n", "}\n", "\n", "int main()\n", "{\n", " test01();\n", "\n", " system(\"pause\");\n", "\n", " return 0;\n", "\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "运行结果: \n", " - 好基友全局函数 正在访问:客厅 \n", " - 好基友全局函数 正在访问:卧室 \n", " - 请按任意键继续. . ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 2. 友元类" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#include \n", "using namespace std;\n", "\n", "//类做友元\n", "class Building; //声明\n", "\n", "class GoodGay\n", "{\n", "public:\n", " GoodGay();\n", "\n", " void visit(); //参观函数 访问Building中的属性\n", "\n", " Building* building;\n", "};\n", "\n", "class Building\n", "{\n", " //GoodGay类是本类的好朋友,可以访问本类的私有成员\n", " friend class GoodGay;\n", "\n", "public:\n", " Building();\n", "\n", "public:\n", " string m_SittingRoom; //客厅\n", "private:\n", " string m_BedRoom; //卧室\n", "};\n", "\n", "//类外写成员函数,写类名的作用域\n", "\n", "//Building构造函数\n", "Building::Building()\n", "{\n", " m_SittingRoom = \"客厅\";\n", " m_BedRoom = \"卧室\";\n", "}\n", "\n", "//GoodGay构造函数\n", "GoodGay::GoodGay()\n", "{\n", " //创建建筑物对象\n", " building = new Building; //这里会调用Building的构造函数\n", " //new是创建什么样的数据类型,就返回什么样的数据类型的指针 \n", "}\n", "\n", "void GoodGay::visit()\n", "{\n", " cout << \"好基友类正在访问:\" << building->m_SittingRoom << endl;\n", "\n", " cout << \"好基友类正在访问:\" << building->m_BedRoom << endl;\n", "\n", "}\n", "\n", "void test01()\n", "{\n", " GoodGay gg; //创建一个GoodGay的对象,会调用GoodGay构造函数,会创建一个building,然后调用building构造函数 \n", " gg.visit();\n", "}\n", "\n", "int main()\n", "{\n", " test01();\n", "\n", " system(\"pause\");\n", "\n", " return 0;\n", "\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "运行结果: \n", " - 好基友类正在访问:客厅 \n", " - 好基友类正在访问:卧室 \n", " - 请按任意键继续. . ." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 3. 成员函数做友元" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#include \n", "using namespace std;\n", "\n", "class Building;\n", "class GoodGay\n", "{\n", "public:\n", " GoodGay();\n", "\n", " void visit(); //让visit函数可以访问Building中私有成员\n", " void visit2(); //让visit2函数不可以访问Buildinng中私有成员\n", "\n", " Building* building;\n", "};\n", "\n", "class Building\n", "{\n", " //告诉编译器,GoodGay类下的visit成员函数作为本类的好朋友,可以访问私有成员 \n", " friend void GoodGay::visit();\n", "\n", "public:\n", " Building();\n", "\n", "public:\n", " string m_SittingRoom; //客厅\n", "\n", "private:\n", " string m_BedRoom; //卧室\n", "};\n", "\n", "// 类外实现构造函数\n", "Building::Building()\n", "{\n", " m_SittingRoom = \"客厅\";\n", " m_BedRoom = \"卧室\";\n", "}\n", "\n", "GoodGay::GoodGay()\n", "{\n", " building = new Building;\n", "}\n", "\n", "// 类外实现成员函数\n", "void GoodGay::visit()\n", "{\n", " cout << \"visit 函数正在访问\" << building->m_SittingRoom << endl;\n", " cout << \"visit 函数正在访问\" << building->m_BedRoom << endl;\n", "\n", "}\n", "\n", "void GoodGay::visit2()\n", "{\n", " cout << \"visit2 函数正在访问\" << building->m_SittingRoom << endl;\n", " //cout << \"visit 函数正在访问\" << building->m_BedRoom << endl;\n", "\n", "}\n", "\n", "void test01()\n", "{\n", " GoodGay gg;\n", " gg.visit();\n", " gg.visit2();\n", "}\n", "\n", "int main()\n", "{\n", " test01();\n", " \n", " system(\"pause\");\n", "\n", " return 0;\n", "\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "运行结果: \n", " - visit 函数正在访问客厅 \n", " - visit 函数正在访问卧室 \n", " - visit2 函数正在访问客厅 \n", " - 请按任意键继续. . ." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3.6.3", "language": "python", "name": "python3.6.3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.3" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": false, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": { "height": "calc(100% - 180px)", "left": "10px", "top": "150px", "width": "341.333px" }, "toc_section_display": true, "toc_window_display": true } }, "nbformat": 4, "nbformat_minor": 4 }