c++中的多态性
2016-05-19 13:27
295 查看
在我们学习c++的过程中我们经常会遇到这样一个词语———多态性那么,什么是多态性呢?1.多态就是一个接口的多种实现2.允许将子类指针赋予父类指针,以让父类可以执行一个或者多个子类的特有功能.如上所示 我们知道类B继承与类A 所以
A* a =
new
B();这句代码是可以编译通过的
我们看看B类对象的内存布局吧:
在这里我们可以看到B的总内存中既有自身的内存 也有继承于A的内存空间那么
A* a =
new
B()这句代码就可以理解为a指向了B中继承于A的那一块内存空间
因此在执行a->foo();这一句代码的时候就找到了A中的foo函数 也就得到最后的结果:ThisisA.以上程序 并未体现多态,下面我们有请多态登场!运行结果:ThisisB是的 正如你所见 在我们加上virtual这个奇怪的关键字后 我们的这句代码a->foo();调用了属于B内存空间的foo (一个父类的指针,被子类对象赋值后,竟然调用了子类的方法!!!!)没错!这就是丧心病狂的多态!为什么会这样捏?当我们的程序在编译的时候 在碰到普通函数(不带virtual关键字的函数)的时候呢,此时就确定了该调用哪个函数,这叫做先期联编,而在碰到了virtual的时候,就会告诉编译器,我们在运行的时候在来确定这个函数的调用者吧!这就叫做滞后联编!那么编译器是怎样实现滞后联编的呢?我们的编译器在编译的时候为每一个包含了virtual函数(虚函数)的类都生成了一张虚函数表,为每一个这种含有虚函数的类的对象都生成了一个虚指针,指针就指向这个虚表,通过这个虚指针指向的虚表就可以在运行时动态的知道该调用什么函数!这里说几个个我曾面试遇到的问题:1.虚表和虚指针是什么时候生成的呢?这个问题我已经解答了: 编译时期2.虚表存在于内存的什么地方呢?如果我们不知道这个答案的话,就会想当然的想,虚表肯定时存在于栈区罗.答案是错误的,经过我上机实验,我发现虚表是存在于内存常量区的 对于这个结果我的想法是:虚表是一张关于虚函数内存地址的记录,在编译时期就已经生成,为了程序的健康运行,肯定是不想要有什么情况去修改我们的虚表的,所有就将虚表存放在了常量内存区3.构造函数和析构函数能否为虚函数呢?1.构造函数:我们知道虚函数是依赖于虚表进行调用的 在构造函数构造之前连虚表的没有 如何去调用虚函数呢 所以 构造函数不可以为虚函数2.析构函数:我们提倡吧析构函数设为虚函数 因为经常会有继承的现象出现 在我们将析构函数设置为虚函数后 可以更好的按类型执行虚函数4.以下程序的输出?class MyClass{public:MyClass(){}; ~MyClass(){};};class VitualClass{public:VitualClass(){};virtual~VitualClass(){};private:};void main(){ //不含虚表的类 和 不含虚指针的对象MyClass a;cout<<sizeof(MyClass)<<endl;cout<<sizeof(a)<<endl;//含虚表的类 和 含虚指针的对象VitualClass b;cout<<sizeof(VitualClass)<<endl;cout<<sizeof(b)<<endl;}运行结果:1144ps:于32位平台上 一个指针占4个字节好了,以上就是我关于多态的一点认识,有不足的地方希望多多指正哦!
相关文章推荐
- C#与.net高级编程 C#的多态介绍
- C#中面向对象编程机制之多态学习笔记
- C#中的多态深入理解
- C#中多态、重载、重写区别分析
- 设计引导--一个鸭子游戏引发的设计理念(多态,继承,抽象,接口,策略者模式)
- C# 面向对象三大特性:封装、继承、多态
- javascript每日必学之多态
- c#基础学习之多态
- PHP面向对象三大特点学习(充分理解抽象、封装、继承、多态)
- 从汇编看c++中多态的应用
- javascript 面向对象全新理练之继承与多态
- Java多态的使用注意事项
- C#使用虚拟方法实现多态
- 实例讲解PHP面向对象之多态
- C#中多态现象和多态的实现方法
- C++基础之this指针与另一种“多态”
- 深入解析C++中的虚函数与多态
- C++多态的实现及原理详细解析
- PHP5中实现多态的两种方法实例分享
- 举例讲解PHP面对对象编程的多态