C++学习笔记(十六):友元

问题的提出:

我们已知道类具备封装和信息隐 藏的特性。只有类的成员函数才能访问类的私有成员,程式中的其他函数是无法访问私有成员的。非成员函数能够访问类中的公有成员,但是假如将数据成员都定义 为公有的,这又破坏了隐藏的特性。另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间开 销,而影响程式的运行效率。

友元是一种定义在类外部的普通函数,但他需要在类体内进行说 明,为了和该类的成员函数加以区别,在说明时前面加以关键字friend。友元不是成员函数,但是他能够访问类中的私有成员。友元的作用在于提高程式的运 行效率,但是,他破坏了类的封装性和隐藏性,使得非成员函数能够访问类的私有成员。

C++中提供三种友元关系的实现方式,友元函数、友元成员函数、友元类。

友元函数:
既将一个普通的函数在一个类中说明为一个friend属性;其定义(大多数会访问该类的成员)应在类后;

友元成员函数:
既然是成员函数,那么肯定这个函数属于某个类,对了就是因为这个函数是另外一个类的成员函数,有时候因为我们想用一个类通过一个接口去访问另外一个类的信息,然而这个信息只能是被它授权的类才能访问;那么也需要用friend去实现;这个概念只是在声明的时候稍有变化;

友元类:
友元类声明会将整个类说明成为另一个类的友元关系;和之前两种的区别是集体和个人的区别;友元类的所有成员函数都可以是另一个类的友元函数;

示例:

 1 using namespace std;
 2
 3 class B;
 4
 5 class A{
 6     private:
 7         int x;
 8     public:
 9         A();
10         void display(B &);
11 };
12
13 class C;
14
15 class B{
16     private:
17         int y;
18         int z;
19     public:
20         B();
21         B(int, int);
22     friend void A::display(B &);//友元成员函数
23     friend void display(B &);//友元函数
24     friend class C;//友元类
25 };
26
27 class C{
28     private:
29         int sum;
30         void calc(B &);
31     public:
32         C();
33         void display(B &);
34 };
35
36 //必须在友元关系的类后进行定义
37 void display(B &v)//友元函数
38 {
39     cout << v.y << " " << v.z << endl;
40 }
41
42 A::A()
43 {
44     this->x = 0;
45 }
46
47 void A::display(B &v)//友元成员函数
48 {
49     this->x = v.y + v.z;
50     cout << this->x << endl;
51 }
52
53 B::B()
54 {
55     this->y = 0;
56     this->z = 0;
57 }
58
59 B::B(int y, int z)
60 {
61     this->y = y;
62     this->z = z;
63 }
64
65 C::C()
66 {
67     sum = 0;
68 }
69
70 void C::display(B &v)
71 {
72     this->calc(v);
73     cout << sum << " = " << v.y << " + " << v.z << endl;
74 }
75
76 void C::calc(B &v)
77 {
78     sum = v.y + v.z;
79 }
80
81 int main()
82 {
83     A a;
84     B b(2, 3);
85     display(b);
86     a.display(b);
87     C c;
88     c.display(b);
89
90     return 0;
91 }
时间: 2024-10-11 17:49:20

C++学习笔记(十六):友元的相关文章

C++学习笔记十六-模板和泛型编程(二)

C++学习笔记十六-模板和泛型编程(二) 16.4 类模板成员 1.模板作用域中模板类型的引用: 通常,当使用类模板的名字的时候,必须指定模板形参.这一规则有个例外:在类本身的作用域内部,可以使用类模板的非限定名.例如,在默认构造函数和复制构造函数的声明中,名字 Queue 是 Queue<Type> 缩写表示.实质上,编译器推断,当我们引用类的名字时,引用的是同一版本.因此,复制构造函数定义其实等价于: Queue<Type>(const Queue<Type> &a

MYSQL进阶学习笔记十六:MySQL 监控!(视频序号:进阶_35)

知识点十六:MySQL监控(35) 一.为什么使用MySQL监控 随着软件后期的不断升级,myssql的服务器数量越来越多,软硬件故障的发生概率也越来越高.这个时候就需要一套监控系统,当主机发生异常时,此时通过监控系统发现和处理. 这个监控实际上是在我们的开发完成之后,这个时候软件就开始在运行,这个运行我们就需要去关注到mysql服务器是否正常,那么我们要观察它就需要给它提供一些监控,这监控就是当它发生故障之后, 那么我们这个监控就会告诉我们到底什么地方发生了一些异常或者一些错误,这个时候我们就

python学习笔记十六 django深入学习一

django 请求流程图 django 路由系统 在django中我们可以通过定义urls,让不同的url路由到不同的处理函数 from . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), #精确匹配 url(r'^articles/([0-9]{4})/$', views.year_archive), #动态路由 url(r'^articles/([0-9]{4})/([0-9]{2

spring in action学习笔记十六:配置数据源的几种方式

第一种方式:JNDI的方式. 用xml配置的方式的代码如下: 1 <jee:jndi-lookup jndi-name="/jdbc/spittrDS" resource-ref="true" id="dataSource"/> 用注解方式的代码如下: 1 @Bean 2 public JndiObjectFactoryBean jndiObjectFactoryBean(){ 3 JndiObjectFactoryBean jndi

yii2源码学习笔记(十六)

Module类的最后代码 1 /** 2 * Registers sub-modules in the current module. 3 * 注册子模块到当前模块 4 * Each sub-module should be specified as a name-value pair, where 5 * name refers to the ID of the module and value the module or a configuration 6 * array that can

[傅里叶变换及其应用学习笔记] 十六. 继续上次内容,晶体成像

x射线晶体照像术 1) x射线是1895年由伦琴(Roentgen)发现的,其波长为$10^{-8}$厘米左右,常用的测量可见光波长的方法会由于其波长太小而无法测量. 2) 晶体(Crystals),晶体的原子结构符合一定规律——原子有序地排列成晶格.劳厄(Laue)在1912年做了一系列著名实验,其目的是利用x射线进行衍射实验来研究晶体的本质. 劳尔假设: 1) x射线是波,因此可以进行衍射 2) 晶体可以充当合适的衍射光栅,即晶体具有晶格原子(lattice atomic)——周期性的原子结

JavaScript权威设计--CSS(简要学习笔记十六)

1.Document的一些特殊属性 document.lastModified document.URL document.title document.referrer document.domain document.write() document.writeIn() 2.查询选取的文本 使用鼠标mouseup事件 3.浏览器定义了多项文本编辑命令(富文本编辑器) 使用Document对象的execCommand()方法. document.queryCommandSupport()判断浏

Android学习笔记十六.Android数据存储与IO.SharedPreferences

SharedPreferences 对于应用程序的数据输入.输出,如果是应用程序只是少量数据需要保存,那么使用普通文件就可以了(SharedPrefereces);但如果应用程序有大量数据需要存储.访问,就需要借助数据库了.Android系统内置了SQLite数据库,SQLite数据库是一个真正轻量级的数据库,它没有后台进程,整个数据库就对应于一个文件. 1.SharedPreferences简介 (1)概念:SharedPreferences保存的数据主要是类似于配置信息格式的数据,因此它保存

PHP学习笔记十六【方法】

<?php //给一个函数传递基本数据类型 $a=90; $b=90.8; $c=true; $d="hello world"; function test1($a,$b,$c,$d) //test1(&$a,&$b,&$c,&$d)//如果是传地址那么值就会改变 { $a=78; $b=89.5; $c=false; $d="beijing"; } //调用函数 test1($a,$b,$c,$d); echo $a.&quo

学习笔记 十六 : Docker

一 docker简介 二 安装配置 三 案例