C++07 reference, upcasting and virtual,多态

引用

  • reference 引用
  • 三种放对象的地方:堆栈,堆,全局数据区
  • 三种访问对象的方式:变量里面放对象,通过指针访问对象,通过引用访问一个对象。
  • 在这里插入图片描述

现在r是c的别名,用r就是在用c。它们是一个东西的两个名字。第三个引用必须初始化。

在这里插入图片描述

const  int& z = x;
//这句话意思是z是x的别名,但是通过z,不能修改x。类似指针

在这里插入图片描述

reference可以做左值, reference实际上是一种指针
binding 绑定

在这里插入图片描述

第三十行 h() = 16 (一个函数的返回结果是个reference, 所以可以做左值, 即放在赋值号的左边。做完以后实际上是x变成16, 因为返回的是x,不是x这个值,而是让x这个变量变成reference给返回。)
explicit 显而易见

在这里插入图片描述

下面主函数使用g(a)来调用这个函数。这个a会被改变的。

在这里插入图片描述

在这里插入图片描述

int&* p 的意思是*p的类型是int的reference,
这是不可以的,因为如果这是可以的话,
意味着我们可以取到reference的地址了,这是不可能的。
只能 int*& p;  可以, 意思是p是reference,它所捆的那个变量是个int 的指针。谁离变量近变量就是啥

在这里插入图片描述

如上图, 如果类的一个成员是reference, 意味着申明它的时候,没有办法给它一个初始值。如果reference是一个本地变量或者一个全局变量, 需要在初始化的时候给它另外一个变量的名字,让它和那个变量捆绑在一起。但如果reference函数的参数或者是成员变量,就没有办法在申明它的时候给它捆绑。因为不知道上图的m_y将来在构造x的对象的时候它要和谁去捆绑在一起。所以必须在构造函数的初始化列表里头把它给写出来

在这里插入图片描述

如上图, 如果要从一个函数里面返回一个reference, 和返回一个指针一样。当函数要返回一个reference的时候, 我们写在return那里的一定是一个直接的变量,没有, & 这些符号。因为这个变量将来在调用这个函数的地方会和一个别的reference结合在一起。所以这个变量 必须是一个有长久生命周期的东西。比如全局变量。*

在这里插入图片描述

**倒数第三行,一个reference赋值给一个double,表面看起来不匹配,但其实可以(int i; int &r = i), 现在发生的事情一样。所以实际上就是把12的值赋给value。下一行实际上是myarray[3] = 34.5, **

在这里插入图片描述

当我们需要传一个对象进一个 函数的时候,用const reference, 几乎这是唯一的方法

Person(const string& name, int weight)

如果没有const, 没有reference,意味着要直接传一个对象进去,要进行大量数据传输。

reference函数要的参数是一个可以做左值的东西,不能写成f(i * 3)什么的。

在这里插入图片描述

向上构造:子类对象可以被当做父类对象来看待,多出来那部分被无视了而已。所以如果有一个子类对象把它当作父类的对象来看的,这件事情就叫做upcast
还有向下构造(downcast有风险)如果拿到了一个对象,是父类的,然后把它当作是子类对象来看。风险比较大。就好像在街上随便找个人(父类是人), 认为他一定是学生(子类是学生),要求他去写作业,这就是downcast。这是不一定的。

cast 类型转换,在OOP情况下,把cast叫做造型(和类型转换不同的就是数据没丢,比如double类型转换成int以后数据丢失,而造型相当于不把学生当学生看,把他当人看。)

在这里插入图片描述

manager是一种特殊的employee

在这里插入图片描述

加粗样式

virtual(虚的), 这个虚的意思是说将来shape类的所有子类里面如果重新写了render,名称一样,参数表也一样。那么这个render和子类里面的render是有联系的。做的事就是让以virtual为前缀的函数有联系,

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

p的静态类型是shape的指针, p的动态类型是它当时指的那个对象的类型是什么如果render函数时virtual的,意味着这是动态绑定, 要看它的动态类型, 如果不是virtual发生的就是静态绑定

这个render是通用函数,对任何shape类的子类都是适用的,只要是shape的子类就一定有render函数。

**virtual的函数在告诉编译器说对这个函数的调用,如果是通过指针或者引用的话,你就不能相信它一定是什么类型,得要到运行的时候才能确定, 这个指针所指的对象是什么类型,你再调那个类型的函数。**这件事就叫做polymorphism(多态性), 在上图p是多态的,p是一个多态对象,因为p里面指了什么类型的对象,通过p做的动作就是那个类型的对象做的。所以p指的是谁,它就变成谁的形态,这就是多态性。

所以多态性建立在两个基础上,一个是upcast(向上构造), 拿一个子类对象过来当父类对象, 第二个是Dynamical bindings(动态绑定)

在这里插入图片描述

多态性实现

  • 任何一个类如果有虚函数,这个类对象就会 比正常的大一点,

  • 所有有virtual的类的对象里面最头上就会自动加上一个隐藏的,不让你知道的指针。那个指针叫做vptr。

  • 这个指针指向一张表,叫做vtable, vtable里面是所有virtual函数的地址。vtable不是对象的,是这个类的。

  • 在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值