粉丝1223获赞6897

相当于对你的类的常见变量的访问开了一个,大家知道面向对象编程的三大特性,封装、继承、多肽。那么封装特性那就是把我有些信息是要隐藏起来了啊,不能被外界访问的。比如说我们定一个类 class x, 那么这个类里头有一个成员对象 a, 那么他被定义成私有了。那么这时候如果我在闷函数里头,然后我要去定一个 class x 对象,那么我是不能直接访问这个对象的 a 变量,因为它是私有的,外界是不能直接访问的。那你要想给外界 a 制这个值的话怎么办呢?那你的类的设计要干什么?要在这里加一个公有的成员方法啊,把这个成员方法呢? a 制的属性值返回给钓鱼。那当然这个方式有坏处,好处这个东西私有了,封装了,外界不可以直接返回了,坏处呢? 显而易见,你如果要通过掉一个函数的方式才能拿到一个变量的值的话,效率一定是低的。那么怎么去解决这个问题? 我绝大多数情况下说风光性给我带来了编程的一定的好,但是在有些特定的场合我需要效率,那这时候在家家里怎么搞呢?那么他设计了一个有缘的概念,所谓的有缘就是我把一个函数 声明为这个类的一个有缘。朋友们啊,我就不管你的这个类里的这些成员啊,是 所有的,是保护的还是公有的,我在我的这个发根函数里头通通可以直接访问,相当于对你的这个类的长权变量的访问开了一个后门。

欢迎回到现代 c 加加编程入门,本期节目是声明并出示化字符串对象,然后输出。那么首先打开代码编辑器,新建一个原文件,命名为字符串对象的声明及出示化点 cpp, 我先写上了基本的程序框架,然后呢我们来写主要内容, 那么自拍对象呢?它是定义在 string 这个图文件里面,所以我们需要将它先引入进来。那么声明自拍对象呢?我们先写上它的类型,那就是 s t d mom out string, 然后它位于 s t d 这个名称空间里面空格,然后呢是编列名称,那么这个呢,我们叫做 h w, 然后呢是一个初始画室, 说实话是里面呢,我们想这个字母串的字面量也是对双引号引起来的一个字母串,这叫 hello, 最好 word, 那这样的话, h w 这个字母串对象呢?我报的字母串就是 hello world, 那么字母串的初始化呢?并不只有的一种方式,我们再看几种 st d 妈妈 stream, 那这个呢,我们叫 hello, 然后呢是初始画室,那初始画室里面首先用双引号写上一个 super 字面料, hello 更好, vlog 就好。那么后面呢,再写一个数字,比如说是因为我们从这个字面量里面要把 hello 这个单词呢 get 出来,这个呢我们叫做部分初始化, 因为这字符串呢,单词号楼有一二三四五个,那么这个意思呢,就是从中音号零开始,然后呢取五个字符作为号楼的初始值, 然后呢再看一个 s, t, d 毛毛 stream, 那这个呢,我们将中间这个逗号呢给它提取出来, come on, 那这次呢,我们使用界面申明好的 h w 这个字符号对象 h w 都好,那这个呢我们后面还可以写两个数字,第一个数字呢就是开始摘取的缩影号,我们数一下一二三 四五,那么所以号呢是零开始的,我们再说一遍,零一二三四五,也就说这逗号呢它,所以号是五,那么它只有一个长度,所以呢我们就摘取一个,那这样的话这个逗号呢就会复制给 come on 这个字谱对象,然后呢再看一个 s t p 猫猫 stream, 这次呢我们将 world 呢再摘出来,同样在前面声明好的支付对象 h w 上进行,那么 world 呢?我们数下它在它的所用号是几 零一二三四五六,再说他的损耗呢是六,同样呢我们可以再往后摘取他一二三四五五个字符,我们可以后面呢提上五,也说从第六个损耗开开始,往后呢摘去五个,因为呢这个字符最后呢就这么多,所以呢我们可以从这个 地址呢取到末尾这个五呢我们就给省略,这样的话 world 的单词呢就会布置给 super 对象 world。 另外呢我们再看一个 s c, d 帽帽 street, 那这次我们选一个 z z z z, 然后呢是个圆括号,圆括号里面呢分两部分,第一个呢是 字符的个数,比如说是三都好,然后第二个呢是字符用单音号引起来,也就说它可以呢用三个字符 z 拼成一个字符串,然后呢将它复制给字符对象 z z。 那么接下来呢,我们输出 sd, 那么代码呢,我们就写完了,按 ctrl 加 s 保存一下,然后来到控制台, 我们通过这个命呢对原文件进行编辑,回车没有任何输出表现并成功。我们通过文件尾呢来调用这个程序查看结果,字符串对向的上面提出画点 exc 回车。

条款三,尽可能使用 const 实际上这个条款没有什么特殊的原因, 只是因为 cost 用途非常广泛,而且你用它和不用它会有区别,你的程序会更健壮,更不容易出错。 那我们先来看一个比较特殊的东西,抗色关键字用于指针时用途非常广泛,那和普通的抗色变量有什么不同呢?因为指针它本身有一个子,就是个弟子子,然后他指向的内容内容也有一个子,所以我们要区分你到底是是说谁不可以改变,对吧? 我们如何区分呢?看在星号的左边还是右边。如果 cost 出现在星号的左边,就表示子像的是常亮,就子像的内容是不能变的。如果 cons 出现在星号的右边,就表示指针它本身的值,也就这个地址是不能变的。我们来看一些例子,这里有一个恰的数组啊,里面放的内容是 hello, 那也就是在内存里面应该是一个 h, 然后 e l l o, 对吧?那么我们用一个叉新指向它,所以 p 这个指针指向的其实是零这个位置, 也就是这个数组里面的第一个元素。好的,没有问题。那现在可以修改吗?没有 cons 吧,新号的左边右边都没有,所以 这个数据是可以修改的,指针本身也是可以修改的。我现在指向你,我,我现以后呢?我可以指向别的地方,这些都没有问题。 好,没有任何限制。我们来看下一个。如果新号的左边出现了 coms, 那不管你是出现在这里或者类型的后面,只要是在新号的左边, 都表示指向的内容,也就数据时长量,你就不能去改它。那你现在想把这个 h 改成 dry 啊,或者什么啊,是不允许的就对吧。所以数据 现在是抗色,是不能改的。但指针本身我这个里面存的地址,我现在是指向的。哈喽,我其实呢也可以指向别的地址,对吧?这是允许的。然后我们再看下一个 新号的右边出现了 const, 就表示指针本身是 const, 那左边没有啊,所以数据是可以修改的。那左右两边都有呢?就都是 cont, 指向 的位置不能改,指向的内容也不能改。好,你只要去关心他是在信号的左边还是右边,或者是左边右边都有就可以了。那 类型的左边右边的其实是一样的,你看着写在类型的左边,看着写在类型的右边,其实是一样的,那表示的都是同样的内容。 f 一接受一个指向这样对象的指针,这样常亮对象的指针,那 f 二呢?一样啊,没有任何区别。这两种用法, cons 出现在类型的左边或者右边是等效的。 如果你能够理解指针的情况,那么对于迭代器呢,应该也是很好的理解啊。因为 st l 也就是标准库的叠加器,是以指针为模型的,因此叠加器的行为就很像 种类型的一种指针。好,我们来看一下下面这个例子。这是一个 rect 容器,一个限量容器里面的每个元素都是硬的型的对象的名称叫做 rect, 因为本身 这个 vector 它是一个模板,对吧?然后加上了一个类型参数,这个才是一个完整的类型,相当于通过这种类型创建的一个对象。 好,那么我们现在分明了一个类型,这是类型前面是 const, 然后是 对象的名称,这个对象其实是一个指针,我们没有看见星号,但是他的行为实际上就是像指针一样,那么我这个 cost 修饰的就是指针本身呀,对吧?你像我们这个 cost, 他修饰的是什么?他修饰的就是这个东西啊, 修饰就是指针,指针的话,如果我们用普通的,普通的指针来解释,这个框子应该出现在星号的右边,对吧?所以如果啊,我们的变量名称是变量的类型是 t, 那么变量的名称不管是什么 都无所谓了,总之他的行为应该是像这样的,你看看是不是这样的,对吧? 那我们可以举个例子啦,比如说 const, 然后呢?我们是一个 inter 星,然后变量的名称,比如说就叫 it, 好,这样可以吧, 这个和我们这种情况不一样啊,写错了,为什么写错了呢?因为 cons 修饰的是它, 它就是一个指针,所以 const 应该写在哪里?写这里吧, const, 这样才对,所以我们应该写成啊,举个例子, content inter const 好取个名字,比如叫 it 呀,或者叫就叫 it, 这样才对。 总之这里要表达的意思就是这个对象,这个迭代器啊,这个迭代器他的行为就像这样,你看 cons 啊,是在信号的右边的,也就是这个迭代器本身是一个长量。 那没有讲数据是常亮吧,你修改里面的内容就修改数据是可以的,但是你想指向别的地方就不可以啊,因为你本身是常亮,然后下面这个呢?如果我要表示内 内容是常亮的,你就用 const iterate 这个类型,类型是不一样的,他已经说的很清楚了,你指向的内容是常亮,所以 c 这个 it e r 啊,这个迭代器它的行为像什么呢?那是不是 cons 应该是在左边的,表示数据是常亮啊,所以应该是类似于这样的行为,你去修改它的内容不可以,对吧?嗯,我们 cons 在左边, 就是如果我们用普通的指针去类比的话,但是你想指向其他地方,可以啊,因为你前面没有写抗色,所以你没有修饰这个指针本身是抗色,或者说, 呃,准确说是你没有修饰这个叠加器本身是 constant。 好,我们再看关于函数的问题, consta 它最 强大的一个用法其实就是源于他在函数声明中的应用。我们看下面这样的一个例子,假设我们要做一个有理数这样的类啊,我们这里面省略了它里面的内容,然后呢,我们做一个操作符重载或者运算符重载。 好,我们要用这两个有理数相乘,让它返回的是 const。 这里面好理解啊,我,我们这两个操作数,我们不打算修改它,所以写 const, 这里面没有指针什么事,对吧?那就是说保护嘛,啊,我不去,不去修改团建的东西,而且用引用,这样也会比较快, 里面参数里面很好理解,但是这个返回值呢?为什么要写成 cost? 我们讲我们这节课讲的重点就是尽可能的需要使用 cost 的时候,尽量去使用它,因 会不一样,那这个他不一样点在哪里呢?那我们看下面这个例子,如果你没有这个限制的话,会出现什么情况啊?我们假设有 a、 b、 c 三个对象,三个这种瓦斯诺的对象, 那么如果我们写成这样呢? a 乘以 b 的结果等于 c, 可以吧?他可以作为组织啊,他不是 count 他这个结果, a 乘 b 的结果,他就是。如果就是一个普通的 rush no 的话,他是可以作为组织的,对吧?那可以进行计算,但这种计算没有任何意义, 有两层,第一层它不是引用啊,如果你没有这个的话,它就是一个临时的一个对象,你给一个临时对象复制有什么意义呢?而且 b a 系可能就不允许。 还有一个问题,我们会写成一乘以二等于三吗?啊?或者说如果啊,不,如果 a、 b 都是 inter 型的话啊,一个 inter 型的 a 乘以 inter 型的 b 会等于 c 吗?你 这样会成立吗?就是在内字的情况,如果 a 和 b 是内字的类型,这样的代码是非法的,很明显都是非法的,对吧?但是你自定义的时候,你是不是要和内字的情况保持一致性呢? 这样才不容易出错。你判断一个你自定义的类型,它的设计的好坏有一个很重要的衡量标准,就是它和我们内置的这些 int 类型啊, hr 类型啊,它的行为是不是一致的? 那如果你前面没有这个康字,那就明显不一致了,那你可能会说,我不会去这样写啊,对吧?这个,这个,你这个太刻意了你,你举这个例子, 那我们就看下面这个例子,有可能你想写的是 a 乘以 b 是不是等于 c, 但是你少写这个等号, 这就不可以了吧?那就是你你写错了呀,变音器不给你提示,因为你前面没有写 const, 如果你有 const 呢?你变音就不通过你就会知道啊。这里面我少写了一个等号, 所以你写不写 cons 好像。嗯,如果你特别小心的情况下是一样的。但实际上呢,你加上 cons, 你的程序就更健壮了啊,更不容易出错了。



这节课我们来学习有缘面向对象四大护法之一的封装,能隐藏对象的内部细节, 将私有及受保护成员保护起来,不让外部访问,以实现面向对象编程的核心理念。但凡事总有例外,封装特性也会遇到例外的情形。打个比方,你的账户余额是绝对不让外人随便查看的, 但是你老婆若要查账,你敢不给吗?为了家庭的和睦,你可能只得牺牲你的封装特性,把你的账户余额向他公开。为了应对这种例外情形,就需要用到有缘,他能打破对象的封装特性, 将特定函数或类可以访问另一个类中的私有成员。有缘可以是函数,称为有缘函数,也可以是类,称为有缘。类有缘可以有三种实现,全局函数作有缘,类作有缘, 以及成员函数做有缘。使用 friend 关键字来声明一个有缘来口头演示。我们先演示全句函数做有缘。首先定义一个老公类,给他一个私有成员账户余额, 再定义他的构造函数传入一个初使账户余额,用传入的参数初使化账户余额成员。 接下来我们定义一个老婆查账的全举函数,传入一个老公类的对象,引用在函数里面,访问老公类的私有成员账户余额,并返回他的值。 可以看到直接这么写是会有语法错误的,这里标红了不能访问内的私有成员。这个时候我们就需要用括号关键字将这个老婆查账函数申名为老公内的有缘函数,函数的原型要与全句函数一致, 这样就没错了。我们来到 main 函数,定义一个老公类的对象, h 给他一个初死的账户余额一百块五毛,然后调用老婆查账函数,输出 h 的 账户余额, 翻译运行,一百块五毛的余额被老婆查到了。全句有源函数的参数,可以传值,可以传整数,也可以传引用。我们现在试一下传整数,将点改成箭头, 再编辑运行,一样可以查到一百块五毛的余额。再试一下传值,箭头改回点,这里不用取地址,编辑运行都是可以的。一百块五毛怎么也逃不过老婆的法眼。 下面来演示类做有缘。我们先把全句函数的有缘代码删掉,来定义一个老婆类,给他一个查账的成员函数传入老公类的对象的引用, 返回老公的账户余额,这里标红,因为他还不是老公类的有缘,所以我们先要在前面声明一下老婆类, 然后再到老公内里面将老婆内声明成有缘,这样就没有错误了。我们到主函数还是定义一个老公内的对象,给他一个一百块五毛的余额, 然后再定义一个老婆对象,然后打印出老婆内的查账方法,让他去查老公的账,并输出到屏幕上 变异运行。我们看到老婆查到了老公的余额。有缘是单向的,即 a 声明 b 是 其有缘, b 可以 访问 a 的 私有成员,但 a 却不是 b 的 有缘, 没有 b 的 私有成员访问权限。就好像汉奸认鬼子当爹,可鬼子却只把汉奸当狗,毫无权力可言。 我们来试一下老婆是老公的有缘,那么老公能够访问老婆的银行账号吗?我们给老婆也加一个账户余额,在他的构造函数中粗死化他的账户余额。 给老公也加一个查账的方法,让他去查老婆的账。传入一个老婆的对象,引用返回老婆的账户余额。 可以看到这里也标红。报错了。虽然老婆是老公的有缘,但是他是单向的,我们把他注视掉。有缘不可传递,既 a 是 名, b 是 其有缘, b 是 名, c 是 其有缘,但 c 不是 a 的 有缘,没有 a 的 私有成员访问权限。 我们再来申明一个老婆类的有缘类,增加一个老王,然后在老婆类里面将老王申明为他的有缘实现。老王类 也给他一个查账的方法,让他查看老婆的账户余额,传入老婆对象的,引用返回他的账户余额。 这里老婆内要加一个各种函数参数,传入他的初使账户余额,然后定义一个老王对象,调用老王的查账方法,让他查看老婆的账户余额,并打印出来 翻译运行。我们看到老王看到了老婆的账户余额一千块, 然后看一下老王能不能查看老公的账户余额。给他加一个查看老公账户余额的成员,返回老公的账户余额。这里不要红了,他虽然是老婆的有缘,但是他却不是老公的有缘,所以这个代码得删掉。 有缘不可继承,即 a 声明 b 是 其有缘, c 是 b 的 派生类,但是 c 无法继承 b 的 有缘权利,没有 a 的 私有成员访问权限。我们再来增加一个新的类老李,让他继承至老王。 给他一个查账方法,让他去查看老婆类的账户余额。传入一个老婆类的对象,返回他的账户余额, 看到这里标红报错了,说明老李不能够从老王那里继承老婆类的有缘的权利,所以这个代码也得删掉。 成员函数作有缘,与全句函数类似,声明时加上内限定即可,语法如下,声明成员函数有缘,则只有指定的成员函数拥有有缘的权利,时间关系就不再掩饰,大家可以自己去尝试。谁家家有缘的分享就到这里下课。