虚函数详解

Posted on 8/4/2022 at 12:00:00 上午

打个比如,有如下的代码片段:inta;int*p=&a;假设p的指针值为0x08004000,并且int类型长度为4字节。

(https://img-blog.csdnimg.cn/20190731201616774.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2ZfX3l1YW4=,size_16,color_FFFFFF,t_70)**去掉virtual关键字,使函数为普通的成员函数**基类大小为4字节,派生类为8字节(无虚函数指针),pb的类型为classBase*的基类指针,对pb进行解引用*pb为基类类型,此时调动的Show方法是基类的Show方法,析构也只执行一次,基类的析构。

通过虚函数表,编译器和程序能够确定调用什么版本的虚函数,尽管使用的是指向/引用基类的指针或者引用。

如:classBase,虚函数联系到多态,多态联系到继承。

纯虚函数在基类中是没有定义的,必须在子类中加以实现,很像java中的接口函数!虚函数引入原因:为了方便使用多态特性,我们常常需要在基类中定义虚函数。

由多态方式调用的时候动态绑定。

在这篇文章中,我只想从虚函数的实现机制上面为大家____一个清晰的剖析。

**静多态**编译阶段确定函数的调用(函数入口地址)静态绑定早绑定通过函数重载和模板来实现**动多态**运行阶段确定函数的调用(函数入口地址)动态绑定晚绑定使用虚函数来实现动多态的实现是在编译期间生成vftable虚函数表,将含有入口地址的虚函数表放入只读数据段,运行时程序会将指令和数据加载到内存上,然后确定函数的入口地址。

实际上,优秀的程序员常常把基类的析构函数定义为虚函数。

同时我们还可以注意到,虚表指针的初始化确实发生在构造函数的调用过程中,但是在执行构造函数体之前,即进入到构造函数的\定义一个对象Bb;调试状态下就可以看到b包含了什么类中只有虚表指针和普通成员(包括const成员)而普通函数,静态成员是不在类中的.

,Base*pb;inheritc;//inherit是继承Base的pb=&c;deletepb;时需要调用对象的析构函数,如果基类析构不是virtual型,会根据pb的定义类型调用相应类的析构函数,即调用即类析构,但如果你在派生类析构里有内存释放操作,那就会发生内存泄漏。

也希望大家多给我提意见。

每个包含虚函数的类的每一个实例包含一个不可见的数据成员vptr(虚函数指针),这个指针被构造函数自动初始化,指向类的vtbl(虚函数表)当客户调用虚函数的时候,编译器产生代码反指向到vptr,索引到vtbl中,然后在指定的位置上找到函数指针,并发出调用。

凡是含有纯虚函数的类叫做抽象类。

言归正传,让我们一起进入虚函数的世界。

虚函数联系到多态,多态联系到继承。

,”

这个参数就是通常我们说的this指针,它的值就是对象的地址。

*2、虚函数声明如下:virtualReturnTypeFunctionName(Parameter)虚函数必须实现,如果不实现,编译器将报错,错误提示为:errorLNK****:unresolvedexternalsymbol”public:virtualvoid__thiscallClassName::virtualFunctionName(void)”*3、对于虚函数来说,父类和子类都有各自的版本。

Posted on 星期四, 8月 4th, 2022 at 上午12:00 In 电脑配件 | Comments RSS

Leave a Reply