SV中句柄与多态

sv中的句柄与操作系统中的句柄不是一回事(操作系统会自动回收内存,一个指针指向一个对象,如果这个对象处于空闲状态,会被释放掉,下次需要的时候再重新分配内存,而指针是指向实际物理内存的,该对象物理内存在变化,相当于它的指针里的值也在动态变化。因此引入句柄,它是某些系统已知的固定内存,它是指针的指针,相当于是指向指针,而指针再指向物理地址。因此在实际运行时,创建某个对象后其句柄是固定的,但是由于操作系统的关系,会给新的物理地址分配一个指针,再把指针的地址给该句柄,相当于每次重新new,会给该对象分配一个新的指针,再把该指针给句柄)

sv中的句柄更接近c++中的指针,都支持多态机制:class A。 A a,此时在栈中存储了a这个指针,它具体的值是随机的,只有当a=new()时,才会在堆中为其分配空间,且把堆中该空间首地址给栈中的a,相当于a指向了堆中的一块空间。而实际上我们的所有程序代码是存在代码区的,换句话说就是内存映射范围内的磁盘上。包括类的数据和函数,当在new()时相当于创建一个实例,而堆中的实例包含的只有数据和虚函数指针,所有的函数都是独一份存在代码区(数据要复制的原因是变量值不一样,但函数永远都一样,只是传入的参数不一样,当采用a.b()这种方式调用函数时会将a赋值给this句柄传给函数b(),this是函数默认传入的句柄)

因此当不是虚函数时,调用某个函数就是去句柄类型对应的类里寻找该函数,这是我们sv的编译原理,也就是句柄类型的作用,而实际所使用的变量则是该句柄所指向实例的变量值。因此如果父类句柄指向子类对象,则会调用父类的函数和子类的变量,但是子类自己的方法无法被使用,但不会出错。而子类句柄指向父类对象时,可以使用子类函数和父类的变量,但是父类没有对应的函数,也可能没有对象函数需要的变量。容易造成错误。因此子类句柄不能指向父类对象。之所以存在父类句柄指向子类对象,是因为父类对象所包括的范围比子类广,在将句柄当作参数传递时,如果指定为父类句柄,可以提高该函数的复用性,处理某一类对象。但是父类句柄无法使用子类的函数,因此存在着$cast函数实现父类到子类句柄的转换,要求必须是父类句柄指向的对象必须是该子类对象,才能完成转换。

而多态是体系在虚函数上,sv借用了c的虚函数表,每个实例都包含虚函数表指针和数据,每个类的实例的虚函数表指针都指向每个类唯一一份虚函数表,子类虚函数表里会继承父类的所有虚函数,因此会有所有父类虚函数的指针,如果子类也定义了同名同参数同返回值的虚函数,就会在表中覆盖父类,当调用a.b(),如果b()是虚函数时,会先去a指向的对象空间里拿虚函数表指针,再去虚函数表里搜索,最终拿到虚函数指针去代码区取虚函数。因此普通函数在编译阶段根据句柄类型就知道去哪里取函数,而虚函数则是在运行过程中new()之后根据其指向的对象才知道去哪里取函数,从而实现函数与对象的动态绑定。说白了就是可以配合句柄类型来使用,用父句柄指向子类型来提高函数复用性,再采用虚函数使得我们不用关系句柄。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值