虚函数与多态实现的机制分析

来源:互联网 发布:数据挖掘的作用和意义 编辑:程序博客网 时间:2024/05/18 04:21

一、基类对象、派生类对象相互访问的规则

没有虚函数时的规则

A:基类能够被派生类对象赋值,只是取了派生类的基类部分进项初始化,
B:  派生类不能被基类对象赋值,因为这样有一部分不能被初始化
C:  基类的对象被派生类对象赋值,但是基类对象仍只能访问自己的函数
D:基类的指针被派生类对象地址赋值,但是基类对象仍只能访问自己的函数
E:建立一个基类的引用,但是赋予派生类对象,其实此引用只是派生类基类部分的引用,仍只能访问基类自己的函数
所以:只有虚函数与指针或引用结合才能实现多态。
所谓多态:在基类建立一个虚函数,派生类对该虚函数进行各自的定义,然后定义一个基类的指针,赋予派生类对象的地址,能够访问派生类的虚函数,而不是虚函数智能访问自己基类的。

二 为什么只有虚函数与指针和引用联合才能实现多态

下面解释为什么
1)为什么基类对象被派生类对象赋值,基类只能访问自己的成员
这其实涉及到了类的赋值构造函数和拷贝构造函数
可以看出,Class A;Class b:public A,
B b;
A a=b;
时调用了拷贝构造函数,因此,只是将b 类的A部分赋值给B,而且还是浅拷贝,所以只能访问基类自己的部分
2)为什么不是虚函数时,基类指针。引用等都不能访问派生类的成员
在内存中,一个基类类型的指针是覆盖N个单位长度的内存空间。
当其指向派生类的时候,由于派生类元素在内存中堆放是:前N个是基类的元素,N之后的是派生类的元素。
于是基类的指针就可以访问到基类也有的元素了,但是此时无法访问到派生类(就是N之后)的元素。
引用的道理也是如此
进一步的:成员函数没有存在类里面,相当于全局函数为什么也不嗯呢该访问呢?
此部分不是很确定,只是附上自己的理解:
基类的指针,用派生类的对象赋值,但是基类指向的还是派生类的基类部分,所以在调用成员函数时,由于this指针,要判断是谁调用它,所以指针带有的还是基类的属性,所以调用的自己的部分。
3当函数为虚函数,基类就可以通过指针或引用访问了
为什么定义为虚函数就可以了呢,这和内存有关系
基类的内存如下:


在内存中,一个基类类型的指针是覆盖N个单位长度的内存空间。当其指向派生类的时候,由于派生类元素在内存中堆放是:前N个是基类的元素,N之后的是派生类的元素。于是基类的指针只能访问到基类自己的元素了,但是无法访问到派生类(就是N之后)的元素。但如图所示虚函数是虚表调用可以访问。所以虚函数的调用通过虚指针,然后派生类的同名虚函数会覆盖基类的虚函数

三、effectiveC++中 by value 传递参数会引起对象切割的原因分析




为什么会切除呢?

原因还是因为,by value 的时候是调用了拷贝构造函数,只是一个值的赋值的过程,相当于创建了一个新的基类对象,只不过是用派生类的基类部分进行初始化而已。而引用没有构造新的对象,只是将派生类的基类部分传了进去。

具体对类的拷贝构造函数和赋值构造函数的深入理解见下篇

1 0
原创粉丝点击