三九宝宝网宝宝教育学龄段教育

求一个包含虚函数的三层继承关系的面向对象的程序要求用虚指针直

02月16日 编辑 39baobao.com

[遗嘱继承有哪些要求]遗嘱继承是指按照立遗嘱人生前所留下的符合法律规定的合法遗嘱的内容要求,确定被继承人的继承人及各继承人应继承遗产的份额。 我国民法规定,公民有处分自己合法所有的个人财...+阅读

用virtual关键字申明的函数叫做虚函数,虚函数肯定是类的成员函数。 存在虚函数的类都有一个一维的虚函数表叫做虚表。类的对象有一个指向虚表开始的虚指针。虚表是和类对应的,虚表指针是和对象对应的。 多态性是一个接口多种实现,是面向对象的核心。分为类的多态性和函数的多态性。 多态用虚函数来实现,结合动态绑定。 纯虚函数是虚函数再加上= 0。

并且该函数只有声明,没有实现。 抽象类是指包括至少一个纯虚函数的类。 那虚函数是如何运行的呢? //Cpp代码 class Base { public: virtual void func() {} } class Derive : public Base { public: void func() {} } void main() { Derive d; Base *pb = &d; b->func(); } 编译器在编译的时候,发现Base类中有虚函数,此时编译器会为每个包含虚函数的类创建一个虚表(即vtable),该表是一个一维数组,在这个数组中存放每个虚函数的地址。

由于Base类和Derive类都包含了一个虚函数func(),编译器会为这两个类都建立一个虚表,(即使子类里面没有virtual函数,但是其父类里面有,所以子类中也有了) 那么如何定位虚表呢?编译器另外还为每个类的对象提供了一个虚表指针(即vptr),这个指针指向了对象所属类的虚表。在程序运行时,根据对象的类型去初始化vptr,从而让vptr正确的指向所属类的虚表。

所以在调用虚函数时,就能够找到正确的函数。 对于上述程序,由于pb实际指向的对象类型是Derive,因此vptr指向的Derive类的vtable,当调用pb->func()时,根据虚表中的函数地址找到的就是Derive类的func()函数。 正是由于每个对象调用的虚函数都是通过虚表指针来索引的,也就决定了虚表指针的正确初始化是非常重要的。换句话说,在虚表指针没有正确初始化之前,我们不能够去调用虚函数。

那么虚表指针在什么时候,或者说在什么地方初始化呢? 答案是在构造函数中进行虚表的创建和虚表指针的初始化。 还记得构造函数的调用顺序吗,在构造子类对象时,要先调用父类的构造函数,此时编译器只“看到了”父类,并不知道后面是否后还有继承者,它初始化父类对象的虚表指针,该虚表指针指向父类的虚表。当执行子类的构造函数时,子类对象的虚表指针被初始化,指向自身的虚表。

对于以上的例子,当Derive类的d对象构造完毕后,其内部的虚表指针也就被初始化为指向Derive类的虚表。在类型转换后,调用pb->func(),由于pb实际指向的是Derive类的对象,该对象内部的虚表指针指向的是Derive类的虚表,因此最终调用的是Derive类的func()函数。 要注意:对于虚函数调用来说,每一个对象内部都有一个虚表指针,该虚表指针被初始化为本类的虚表。

所以在程序中,不管你的对象类型如何转换,但该对象内部的虚表指针是固定的,所以呢,才能实现动态的对象函数调用,这就是C++多态性实现的原理。 总结(基类有虚函数): 每一个类都有虚表。 虚表可以继承,如果子类没有重写虚函数,那么子类虚表中仍然会有该函数的地址,只不过这个地址指向的是基类的虚函数实现。如果基类有3个虚函数,那么基类的虚表中就有三项(虚函数地址),派生类也会有虚表,至少有三项,如果重写了相应的虚函数,那么虚表中的地址就会改变,指向自身的虚函数实现。

如果派生类有自己的虚函数,那么虚表中就会添加该项。 派生类的虚表中虚函数地址的排列顺序和基类的虚表中虚函数地址排列顺序相同。

以下为关联文档:

求一个公共关系的策划公关策划(Public Relation Planning) 编辑本段【名词解释】 公关策划的目标是指组织通过公共关系策划和实施达到理想的形象状态和标准。 公关策划即“公共关系策划”,是公共关...

使用uml进行面向对象分析与设计使用到哪些视图第 1 页 共 8 页 农业大学期末考试试卷(A卷)-答案 2007学年第1学期 考试科目: 面向对象分析与设计 考试类型:(闭卷) 考试时间: 120 分钟 学号 姓名 年级专业 题号 一 二 三 四 五...

面向对象程序设计课程设计#include#include#includeclass stu { char name[20]; double math,chinese,english,average,sum; public: stu() { } stu(char n[20],double ma,double chin,double eng) {...

什么是多态性什么是虚函数为什么要定义虚函数多态性定义:由继承而产生的相关的不同的类,向其对象发送同一个消息,不同的对象接收到后会产生不同的行为(即方法)。 在某基类中声明为 virtual 并在一个或多个派生类中被重新定...

C虚函数和多态性我写的代码是:#include#include using namespace std; class base{ public: base(string temp="小雨") { name=temp; } virtual void setname(string name) { this->name=name;...

如何解析多维数组和指针的关系大家都知道一维数组名即是一个指针常量,它代表数组第一个元素的地址,我们知道一维数组的长度,那么可以通过数组名输出一维数组的所有元素:#include int main(void) { int i;int...

面向对象分析中的三种主要模型是什么?它们之间有什么关系三种主要模型是对象模型、功能模型、动态模型。他们有三个不同但又密切相关的角度模拟目标系统。对象模型是最基本、最核心、最重要的3个模型之间具有下述关系。 (1)与功能模...

设计一个含有静态成员静态成员函数的程序分析程序结果理解静题目本身不困难,让我纠结的是 你干嘛类A不定义 构造函数。 1 add的定义 为什么需要在类A声明友元函数呢,因为全局函数add需要调用类A的私有变量x, 如果add本身就是类A的成员函...

用C语言编写一个程序要求用户自己设计一个迷宫从出口出发#include#include#include#include#include#define x1 (a-120)/20#define y1 (b-40)/20#define UP 72#define DOWN 80#define LEFT 75#define RIGHT 77#define ENTER 13#def...

推荐阅读
图文推荐