600字范文,内容丰富有趣,生活中的好帮手!
600字范文 > C++:多态与虚函数 纯虚函数

C++:多态与虚函数 纯虚函数

时间:2023-12-25 16:47:16

相关推荐

C++:多态与虚函数 纯虚函数

1.多态的机制与虚函数的机制

1.1 多态的机制

1.当在类中使用virtual声明一个函数为虚函数时,在编译时,编译器会自动在基类中默默地安插一个虚函数表指针,同时的.rodata段为这类生成一张虚函数表,用来保存类中的虚函数的地址。

2.当继承发生时,父类中的虚指针就被子类给继承了下来,所以他的类对象空间就增大了一个指针的大小。

3.当子类构造对象时,这根继承而来的虚指针,将会在子类的构造函数中被重新赋值,所赋的值即为子类类中产生的虚函数表地址。

4.当使用父类指针或引用,对虚函数进行调用时,通过这个虚函数表指针,在虚函数表中查找虚函数的地址,从而调用不同类的虚函数。

1.2 虚函数的机制

虚函数的意义何在?就是用来承接动态多态的。他是如何承接这种动态多态机制的呢?

当子类之中函数与父类之中的虚函数重名时,且返回值与形参列表都一致时,将是对父类虚函数的重写。当在子类重写虚函数时,将会把虚函数表中的父类的虚函数地址覆盖掉。

注释:虚函数的具体可以去看主页文章,单继承与多进程

1.3虚函数表的结构图

1.4动态多态实现的三个前提件(很重要)

1.有继承关系

2.基类中有虚函数,且子类重写虚函数

3.基类指针或引用,指向或引用父类对象,就会形成动态多态

2.多态实例应用

#include <iostream>using namespace std;class Driver{public:virtual void show_info(){cout<<"我是司机"<<endl;}};class Bwm:public Driver{public:void show_info(){cout<<"我开的是宝马"<<endl;}};class Benchi:public Driver{public:void show_info(){cout<<"我开的是奔驰"<<endl;}};class Tuolaji:public Driver{public:void show_info(){cout<<"我开的是拖拉机"<<endl;}};class Kai{public:void kaiche(Driver& p){p.show_info();}};int main(){Bwm bwm;Tuolaji tuolaji;Benchi benchi;Kai p;p.kaiche(tuolaji);p.kaiche(benchi);p.kaiche(benchi);return 0;}

结果图:

3.多态的巨大问题与虚析构

3.1代码举例说明

#include <iostream>using namespace std;class A{public:A(){cout<<"A的构造"<<endl;}~A(){cout<<"A的析构"<<endl;}virtual void show_info(){cout<<"爱吃饭"<<endl;}};class B:public A{public:B(){cout<<"B的构造"<<endl;}~B(){cout<<"B的析构"<<endl;}void show_info(){cout<<"爱吃糖"<<endl;}};int main(){A* a=new B;a->show_info();delete a;return 0;}

结果图:

由图可知:当用虚函数实现多态的时候,子类的的析构无法进行。

所以我们应该怎么解决呢?

3.2代码实现

#include <iostream>using namespace std;class A{public:A(){cout<<"A的构造"<<endl;}virtual~A(){cout<<"A的析构"<<endl;}virtual void show_info(){cout<<"爱吃饭"<<endl;}};class B:public A{public:B(){cout<<"B的构造"<<endl;}~B(){cout<<"B的析构"<<endl;}void show_info(){cout<<"爱吃糖"<<endl;}};int main(){A* a=new B;a->show_info();delete a;return 0;}

结果图:

所以,为了避免子类的析构无法执行而造成的内存泄漏问题,应该把最远端父类的析构函数定义为虚析构。虚析构的语法即是在最远端父类的析构函数名前 加virtual进行修饰即可。

虚析构如下:

virtual~A(){//虚析构的定义形式。}

4.纯虚函数与抽象类

4.1纯虚函数语法格式:

class + 类名{public:virtual void showInfo() = 0; };

4.2纯虚函数的定义

在类中定义一个没有函数体的虚函数就叫做纯虚函数。类中有纯虚函数的类就叫做抽象类。抽象类被人称接口类。这个纯虚函数只有一个函数名做为函数功能的表现,而没有函数体的实现。纯虚函数必须在子类之中进行实现,如果继承的子类没有实现父类的纯虚函数,那么这个子类也将成员抽象类。抽象类是不可以定义对象的。纯虚函数也叫接口类中的接口。

4.3抽象类的应用实例

#include <iostream>using namespace std;class A{public:virtual void show_info()=0;virtual void goshopping()=0;};class B:public A{public:void show_info(){cout<<"我是大哥"<<endl;}void goshopping(){cout<<"我是小弟"<<endl;}};int main(){A* a=new B;a->show_info();a->goshopping();return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。