C++虚函数virtual

一、构造函数不能是虚函数

首先需要了解 vptr指针和虚函数表的概念,以及这两者的关联。

vptr指针指向虚函数表,执行虚函数的时候,会调用vptr指针指向的虚函数的地址。

当定义一个对象的时候,首先会分配对象内存空间,然后调用构造函数来初始化对象。vptr变量是在构造函数中进行初始化的。又因为执行虚函数需要通过vptr指针来调用。如果可以定义构造函数为虚函数,那么就会陷入先有鸡还是先有蛋的循环讨论中。

二、基类的析构函数必须是虚函数

我们都知道,想要回收一个对象申请的资源,那么就需要调用析构函数。虽然我们没有显示地调用析构函数,但是编译器都会默认地为我们执行析构函数。

那么当我们执行 BaseClass *base = new BaseClass(); 当我们执行 delete base时,会调用析构函数为我们释放资源。而 我们执行BaseClass *sub = new SubClass(); 如果BaseClass基类的析构函数不是虚函数的时候,delete sub 对象的时候,只会释放BaseClass 基类申请的资源,而不是释放SubClass派生类的资源。原因如下:

基类指针指向了派生类对象,而基类中的析构函数是非virtual的,而虚构函数是动态绑定的基础。现在析构函数不是virtual的,因此不会发生动态绑定,而是静态绑定,指针的静态类型为基类指针,因此在delete的时候只会调用基类的析构函数,而不会调用派生类的析构函数。这样,在派生类中申请的资源就不会得到释放,就会造成内存泄漏,这是相当危险的:如果系统中有大量的派生类对象被这样创建和销毁,就会有内存不断的泄漏,久而久之,系统就会因为缺少内存而崩溃。

当然,如果在派生类中没有动态申请有资源的时候,是不会造成内存泄漏的。而当派生类对象的析构函数中有内存需要回收,并且在编程过程中采用了基类指针指向派生类对象,如为了实现多态,并且通过基类指针将对象销毁,这时,就会因为基类的析构函数为非虚函数而不触发动态绑定,从而没有调用派生类的析构函数而导致内存泄漏。
因此,为了防止这种情况下的内存泄漏的发生,最后将基类的析构函数写成virtual虚析构函数。

三、虚函数不能是static

原文:https://blog.csdn.net/gochenguowei/article/details/79682681

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 什么叫多态性? A:同样的消息被不同类型的对象接收时,对象会采用完全不同的行为处理消息。 多态性有几种? A:静态...
    凉拌姨妈好吃阅读 662评论 0 0
  • 1 虚函数 函数声明前加上virtual。如果定义的类将被用做是基类,则应该将那些要在派生类中重新定义的类方法声明...
    yanggali99阅读 1,038评论 0 0
  • C++虚函数 C++虚函数是多态性实现的重要方式,当某个虚函数通过指针或者引用调用时,编译器产生的代码直到运行时才...
    小白将阅读 1,761评论 4 19
  • 一、认识虚函数 虚函数(Virtual Function):在基类中声明为 virtual 并在一个或多个派生类中...
    Sky_Mao阅读 1,390评论 0 1
  • 1 解决什么问题 让基类指针可以调用派生类的函数,达到多态的效果。设计抽象基类时,找出哪此操作行为与类型相关。有哪...
    丢番图阅读 197评论 0 0