{"id":"58954457","type":"page","status":"current","title":"05.友元","version":{"by":{"type":"known","username":"ethanliu","userKey":"2c90931b6cfb654f016d5c69becc0001","profilePicture":{"path":"/images/icons/profilepics/default.svg","width":48,"height":48,"isDefault":true},"displayName":"刘浩","_links":{"self":"https://wiki.suncaper.net/rest/api/user?key=2c90931b6cfb654f016d5c69becc0001"},"_expandable":{"status":""}},"when":"2022-07-09T01:51:24.000Z","message":"","number":1,"minorEdit":false,"hidden":false,"_links":{"self":"https://wiki.suncaper.net/rest/experimental/content/58954457/version/1"},"_expandable":{"content":"/rest/api/content/58954457"}},"body":{"storage":{"value":"

4.5 友元

类的主要特点之一是数据隐藏,即类的私有成员无法在类的外部(作用域之外)访问。但是,有时候需要在类的外部访问类的私有成员,怎么办?

解决方法是使用友元函数,友元函数是一种特权函数,c++允许这个特权函数访问私有成员。这一点从现实生活中也可以很好的理解:

比如你的家,有客厅,有你的卧室,那么你的客厅是Public的,所有来的客人都可以进去,但是你的卧室是私有的,也就是说只有你能进去,但是呢,你也可以允许你的闺蜜好基友进去。

程序员可以把一个全局函数、某个类中的成员函数、甚至整个类声明为友元。

4.5.1 友元语法

  • friend关键字只出现在声明处
  • 其他类、类成员函数、全局函数都可声明为友元
  • 友元函数不是类的成员,不带this指针
  • 友元函数可访问对象任意成员属性,包括私有属性
cppmSittingRoom = \"客厅\";\n\tthis->mBedroom = \"卧室\";\n}\n\nint main(){\n\n\tBuilding building;\n\tMyFriend myfriend;\n\n\tCleanBedRoom(building);\n\tmyfriend.LookAtBedRoom(building);\n\tmyfriend.PlayInBedRoom(building);\n\n\tsystem(\"pause\");\n\treturn EXIT_SUCCESS;\n}]]>

 

    [友元类注意]

1.友元关系不能被继承。

2.友元关系是单向的,类A是类B的朋友,但类B不一定是类A的朋友。

3.友元关系不具有传递性。类B是类A的朋友,类C是类B的朋友,但类C不一定是类A的朋友。

思考: c++是纯面向对象的吗?

如果一个类被声明为friend,意味着它不是这个类的成员函数,却可以修改这个类的私有成员,而且必须列在类的定义中,因此他是一个特权函数。c++不是完全的面向对象语言,而只是一个混合产品。增加friend关键字只是用来解决一些实际问题,这也说明这种语言是不纯的。毕竟c++设计的目的是为了实用性,而不是追求理想的抽象。

                                                       --- Thinking in C++

4.5.2 课堂练习

请编写电视机类,电视机有开机和关机状态,有音量,有频道,提供音量操作的方法,频道操作的方法。由于电视机只能逐一调整频道,不能指定频道,增加遥控类,遥控类除了拥有电视机已有的功能,再增加根据输入调台功能。


","representation":"storage","_expandable":{"content":"/rest/api/content/58954457"}},"_expandable":{"editor":"","view":"","export_view":"","styled_view":"","anonymous_export_view":""}},"extensions":{"position":"none"},"_links":{"webui":"/pages/viewpage.action?pageId=58954457","edit":"/pages/resumedraft.action?draftId=58954457","tinyui":"/x/2ZKDAw","collection":"/rest/api/content","base":"https://wiki.suncaper.net","context":"","self":"https://wiki.suncaper.net/rest/api/content/58954457"},"_expandable":{"container":"/rest/api/space/2CT","metadata":"","operations":"","children":"/rest/api/content/58954457/child","restrictions":"/rest/api/content/58954457/restriction/byOperation","history":"/rest/api/content/58954457/history","ancestors":"","descendants":"/rest/api/content/58954457/descendant","space":"/rest/api/space/2CT"}}