首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【C++】多态 ⑤ ( 虚析构函数 | 虚析构函数语法 | 虚析构函数意义 | 父类指针指向子类对象情况下父类和子类使用 virtual 虚析构函数 | 代码示例 )

A 的构造函数 , 然后调用 B 的构造函数 , 最后调用 C 的构造函数 ; 参考 【C++】继承 ⑧ ( 继承 + 组合 模式的类对象 构造函数 和 析构函数 调用规则 ) 博客中 , 构造函数...子类 中覆盖 父类 的 析构函数 ; 场景说明 : A 类 是基类 , B 类 继承 A 类 ; 声明一个 A 类型 的指针变量 , 为其赋值 B 类型对象的地址 , 当需要释放该指针变量时 , 使用...; 当使用 父类 指针指向一个 子类 对象时 , 如果要通过 delete 释放该指针指向的对象 , 如果是正常的析构函数 , 没有 使用 virtual 定义虚析构函数 , 则只会调用 父类 的 析构函数..., 只有在 父类 的析构函数是 虚函数 时 , 子类 的析构函数才必须是虚函数 ; 如果 父类 的 析构函数 不是 虚函数 , 则 子类 的 析构函数 可以是 普通的 非虚函数 ; 二、代码示例 -...在下面的代码中 , 将 父类 和 子类 的析构函数 , 都使用 virtual 关键字修饰 ; 声明 子类指针 指向 子类对象 , 释放 子类指针 时 先调用 子类析构函数 , 再调用父类析构函数 ;

1.4K20

C++类的构造函数与析构函数

C++中每个类都有其构造与析构函数,它们负责对象的创建和对象的清理和回收,即使我们不写这两个,编译器也会默认为我们提供这些构造函数。...下面仍然是通过反汇编的方式来说明C++中构造和析构函数是如何工作的。...编译器是否真的会默认提供构造与析构函数 在一般讲解C++的书籍中都会提及到当我们不为类提供任何构造与析构函数时编译器会默认提供这样六种成员函数:不带参构造,拷贝构造,“=”的重载函数,析构函数,以及带const...由于默认的拷贝构造是进行简单的内存拷贝,所以当类中的成员中有指针变量时尽量自己定义拷贝构造,进行深拷贝,否则在以后进行析构时会崩溃。...,但是接着执行类的析构函数析构在函数中定义的类对象,接受返回值得这块内存一直等到它所在的语句块结束才调用析构 如果不要这个返回值时又如何呢,下面的代码说明了这个问题 int main() {

1.6K10
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    C++核心准则​讨论:将基类的析构函数设为公共和虚拟的,或受保护的和非虚拟的

    析构函数应该是虚函数吗?也就是说,是否应该允许通过指向基类的指针进行销毁?如果是,则base的析构函数必须是公共的才能被调用,否则虚拟调用它会导致未定义的行为。...如果Base的析构函数是公共的和非虚拟的(默认值),则可能会意外地在实际上指向派生对象的指针上调用它,在这种情况下,尝试删除的行为是不确定的。...如第39项所述,对于普通成员函数,选择之间是允许以非虚拟方式(通过指向Base的指针)调用它(但如果它调用虚拟函数(例如在NVI或模板方法模式中),则可能具有虚拟行为) ),实际上还是根本没有。...析构可以看作只是另一种操作,尽管具有使非虚调用变得危险或错误的特殊语义。因此,对于基类析构函数,选择是根据是否允许通过指向Base的指针实际上调用它。“非虚”不是一种选择。...因此,如果可以调用(即是公共的)基类析构函数,则它是虚拟的,否则是非虚拟的。

    1.1K20

    C++新旅程:类的构造函数和析构函数

    而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作。3.2特性(1) 析构函数名是在类名前加上字符 ~。(2)无参数、无返回值类型。(3) 一个类只能有一个析构函数。...若未显式定义,系统会自动生成默认的析构函数。注意:析构函数不能重载 (4)对象生命周期结束时,C++编译系统系统自动调用析构函数。...原本按照我们之前案例得出的结论最先析构的应该是d5,最后析构的应该是d1才对,是哪里出了问题呢?其实问题出在这些对象的生命周期上,下面简要介绍一下各种对象的生存期,以及调用构造函数、析构函数的时机。...当程序即将结束前,全局对象的析构函数会被执行。4、静态全局对象静态全局对象与全局对象类似,其构造函数也是在程序一开始时被执行。...一般的全局对象在程序的其他文件中可以通过关键字extern来访问,而静态全局对象则只能在本文件中使用。综上所述,静态全局对象和全局对象的生命周期实际上是相同的,都是贯穿整个程序的执行过程。

    5610

    面试题:基类的析构函数为何要声明为虚函数?

    面试题:基类的析构函数为何要声明为虚函数? 在 C++ 中,一个类的析构函数用于释放它的实例占用的资源。如果没有正确地释放这些资源,就可能会导致内存泄漏和其他严重的问题。...基类的析构函数到底是否需要声明为虚函数取决于你是否会使用继承体系。 当使用继承时,如果一个基类指针指向了一个派生类对象,当对指针进行 delete 操作时,应该同时调用基类和派生类的析构函数。...如果基类的析构函数不是虚拟函数,则运行时不能确认要调用哪个析构函数。如果它是虚拟的,则始终将调用最实际对象的析构函数。...在 main() 函数中,通过基类指针创建一个 Dog 类型的对象,然后删除指针。...总结 在使用继承时,应该将基类的析构函数声明为虚函数,这样可以确保在运行时删除派生类对象时同时调用基类和派生类的析构函数。否则运行时不能确认要调用哪个析构函数,并且可能导致内存泄漏和其他问题。

    4700

    C++编程经验(2):为虚基类做虚析构函数的必要性

    这个要提一下,如果记不住就记住:如果不做虚析构函数,会有内存泄漏 解释 定义一个基类的指针p,在delete p时,如果基类的析构函数是虚函数,这时只会看p所赋值的对象,如果p赋值的对象是派生类的对象,...就会调用派生类的析构函数;如果p赋值的对象是基类的对象,就会调用基类的析构函数,这样就不会造成内存泄露。...如果基类的析构函数不是虚函数,在delete p时,调用析构函数时,只会看指针的数据类型,而不会去看赋值的对象,这样就会造成内存泄露。 多少学点设计模式就清楚了。...接下来是一个子类 class Inherit :public Base{ //此处省去,一切从简 }; //重点看调用 int main() { Base *p = new Inherit; //这种方式的调用...,这时候有没有虚析构就不一样了 delete p; Base *q = new Base; delete q; return 0; }

    59710

    C++核心准则C.35:基类的析构函数要么是公开的虚函数,要么是保护的非虚函数

    C.35: A base class destructor should be either public and virtual, or protected and nonvirtual 基类的析构函数要么是公开的虚函数...为了避免无定义的行为。如果析构函数是公有的,那么调用侧的代码就会尝试使用基类指针销毁派生类的对象,在基类的析构函数为非虚函数时其结果时没有定义的。...如果析构函数时保护的,那么调用侧代码就无法通过基类类型指针销毁派生类对象,这是析构函数就没有必要一定是虚函数。析构函数是保护而不是私有的,这样派生类的析构函数才能调用它。...通常,基类的设计者不会知道在析构函数中应该执行什么样的动作。...我们可以想象一种需要保护的虚函数析构函数的情况:当希望允许派生类的对象(只有这个类型)通过基类指针销毁另外一个对象(不是它自己)时。但是我们还没有在实际的开发中遇到这种情况。

    1.1K20

    C++核心准则C.127:包含虚函数的类应该有虚析构函数或保护析构函数‍

    C.127: A class with a virtual function should have a virtual or protected destructor C.127:包含虚函数的类应该有虚析构函数或保护析构函数‍...包含虚函数的类通常(大多数情况下)通过指向基类的指针使用。通常,最后一个使用者必须通过指向基类的指针调用delete操作,通常是指向基类的智能指针,因此析构函数应该是公开的虚函数。...稍微特殊一些的情况是:如果不希望支持通过指向基类的指针销毁对象,析构函数应该是保护的非虚函数。参见C.35。...包含虚函数的类的析构函数要么是公开的虚函数,要么是保护的非虚函数。...提示针对包含虚函数却没有虚析构函数的类的销毁操作。

    78220

    工作中常见的几种内存泄漏场景汇总

    3、基类中的析构函数引发的内存泄露 在C++中,如果子类的对象是通过基类的指针进行删除,如果基类的析构函数不是虚拟的,那么子类的析构函数可能不会被调用,从而导致派生类资源没有被释放,进而产生内存泄漏。...函数中定义了一个基类的指针,并指向其子类对象,随后对基类指针进行释放,本意是想通过对基类指针释放同时也调用子类的析构函数释放子类资源。...这是因为,在基类中并没有定义析构函数,在这种情况下,编译器会为我们默认生成一个析构函数,但还不够智能,生成的析构函数不是虚拟的,这样在对基类指针进行析构时就不能调用子类析构函数释放资源。...如果想要达到我们想要的效果,只需将基类中的析构函数定义成虚析构即可。修改后运行结果如图所示: 可见,子类中的资源得到正常释放。...但是这样做就破坏了delete的工作原理,delete删除对象时,先调用对象的析构函数,再delete指针对象,上面的代码在将pBase转换成void*后,delete获取不到析构对象的类型就不能正确调用对象的析构函数

    1.1K20

    面试题:什么是虚函数?

    面试题:什么是虚函数? 在 C++ 中,虚函数是一种特殊的成员函数,它允许在基类中使用 virtual 关键字声明,在派生类中进行重写,并且可以通过基类指针或引用调用派生类的成员函数。...调用虚函数 虚函数通过基类指针或引用来调用派生类的成员函数。...虚析构函数 还有一个非常重要的内容:如果你在具有派生类的基类析构函数中不是将析构函数声明为虚拟,则不会删除具有派生类对象的基类指针的派生类对象。...此时,Animal 的析构函数不是虚函数,所以当使用的时候调用是 Animal 的析构函数。因此,如果您计划通过一个基类指针删除派生的对象,请将基类的析构函数声明为虚拟的。...总结 虚函数是 C++ 中实现多态的重要机制之一,它允许在基类中声明函数为虚拟函数,在派生类中进行重写,并且可以通过基类指针或引用调用派生类的成员函数。

    6300

    每日一问06 构造函数可以是虚函数吗

    ,为什么 和普通函数对比 首先,C++不支持虚拟构造函数。...我的误区 根本说不清楚:直接回答vptr构造 不相关, 不懂 构造函数无法通过指针访问原理,new 如何调用类构造函数申请的用法。...根本说不清楚:必须创建好了,才能用,不懂 抽象和具体关系.接口不属于具体一个类 析构函数可以是虚函数吗,为什么 参考思路: 可以是 析构函数 执行顺序是 派生类 ,基类 如果析构函数不被声明成虚函数,则编译器实施静态绑定...,在删除指向派生类的基类指针时,只会调用基类的析构函数而不调用派生类析构函数,这样就会造成派生类对象析构不完全。...如果声明了,触发 派生类 ,基类 正确析构顺序。

    70930

    《逆袭进大厂》第二弹之C++进阶篇59问59答(超硬核干货)

    假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数。...,在销毁一个对象时,先调用子类的析构函数,然后再调用基类的析构函数。...假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数。...2) 纯虚析构函数一定得定义,因为每一个派生类析构函数会被编译器加以扩张,以静态调用的方式调用其每一个虚基类以及上一层基类的析构函数。...虚拟继承基类的子类中,子类会增加某种形式的指针,或者指向虚基类子对象,或者指向一个相关的表格;表格中存放的不是虚基类子对象的地址,就是其偏移量,此类指针被称为bptr,如上图所示。

    2.4K40

    后台开发:核心技术与应用实践 -- C++

    而对于有虚函数的类来说,每个对象都会保存一个指向虚函数表的指针,该指针在64位的机器上占8Byte。...在派生时,派生类是不能继承基类的析构函数的,也需要通过派生类的析构函数去调用基类的析构函数。...在派生类中可以根据需要定义自己的析构函数,用来对派生类中所增加的成员进行清理工作;基类的清理工作仍然由基类的析构函数负责。...在执行派生类的析构函数时,系统会自动调用基类的析构函数和子对象的析构函数,对基类和子对象进行清理。...C++明确指出,当derived class 对象经由 base class 指针被删除 而该 base class 带着一个non-virtual 析构函数, 导致对象的 derived 成分没被销毁掉

    1.3K10

    轻松搞定面试中的“虚”

    是否每个类的析构函数都要设置成virtual?是否可以将析构函数设置成内联函数。 这样做是为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用。...在析构的时候会首先调用子类的析构函数,析构掉对象中的子类部分,然后在调用基类的析构函数析构基类部分,如果在基类的析构函数里面调用虚函数,会导致其调用已经析构了的子类对象里面的函数,这是非常危险的。...虚拟继承与普通继承不同的是,虚拟继承可以防止出现diamond继承时,一个派生类中同时出现了两个基类的子对象。也就是说,为了保证这一点,在虚拟继承情况下,基类子对象的布局是不同于普通继承的。...因此,它需要多出一个指向基类子对象的指针。 8.什么是虚函数表?...为实现动态联编,编译器为每个包含虚函数的类创建一个表,称为vtable,在vtable中,编译器放置了特定类的虚函数地址,在每个带有虚函数的类中编译器会秘密地设置一个虚函数表指针,称为vptr,指向对象的

    68120

    C++ this指针:用于在成员函数中指向调用该函数的对象

    C++中this指针是一个指向当前对象的指针。在成员函数中,可以使用this指针来访问调用该函数的对象的成员变量和成员函数。...一、定义和使用this指针 this指针是在成员函数内部定义的一个常量指针。它存储了当前对象的地址,可以通过它访问当前对象的成员变量和成员函数。...二、作为返回值的this指针 this指针可以作为返回值返回。这种情况下,返回的是指向调用该函数的对象的指针。为了实现这个功能,需要将返回类型设置为类的引用或指针类型。...函数内部,返回的是指向调用该函数的对象的指针。...四、总结 this指针在C++中是一个非常重要的概念,可以用来访问调用该函数的对象,作为返回值返回,或者作为函数参数传递。掌握this指针的使用可以帮助我们更好地编写面向对象的程序。

    26140

    计算机考研复试C语言常见面试题「建议收藏」

    使用智能指针可以很大程度上的避免这个问题,因为智能指针就是一个类,当超出了类的作用域时,类会自动调用析构函数,析构函数会自动释放资源。...在基类中实现纯虚函数的方法是在函数原型后加“=0” 如:virtual void funtion1()=0 如果A中的virtual去掉以后,以上的结果将会是A的foo 16、为什么析构函数必须是虚函数...为什么C++默认的析构函数不是虚函数 析构函数设置为虚函数可以保证我们new一个子类时,可以使用基类指针指向该子类对象,释放基类指针时可以释放掉子类的空间,防止内存泄漏。...C++默认的析构函数不是虚函数是因为虚函数需要额外的虚函数表和虚表指针,占用额外的内存。而对于不会被继承的类来说,其析构函数如果是虚函数,就会浪费内存。...19、类构造和析构顺序 构造: 基类成员对象的构造函数 基类的构造函数 子类成员对象的构造函数 子类的构造函数 析构: 子类的析构函数 子类成员的析构函数 基类的析构函数 基类成员的析构函数 两者正好相反

    1.7K30

    十一、多态

    在C++中,多态主要通过虚函数来实现,并涉及以下三个关键要素: 继承关系 说明:多态必须发生在具有继承关系的类之间。即,一个类(子类或派生类)必须从另一个类(父类或基类)继承而来。...当通过基类指针删除派生类对象时,如果基类的析构函数不是虚的,那么只会调用基类的析构函数,而不会调用派生类的析构函数。...这可能导致资源泄漏或未定义行为,因为派生类可能分配了需要手动释放的资源(如动态分配的内存、文件句柄等)。 使用场景: 当通过基类指针删除派生类对象时,确保派生类的析构函数被调用。...虚析构函数确保通过基类指针删除派生类对象时,派生类的析构函数会被调用,从而安全地释放资源。...构造和析构过程中虚函数表指针的行为是特殊的,需要特别注意。 总之,虚函数表指针是C++多态性实现的底层机制之一,它使得通过基类指针或引用来调用虚函数时,能够根据对象的实际类型来调用相应的函数实现。

    10110

    解锁C++多态的魔力:灵活与高效的编码艺术(上)

    2.4 虚析构函数(Virtual Destructor)的重写 在C++中,虚析构函数(Virtual Destructor)是一种特殊的析构函数,通过在基类中将析构函数声明为虚函数,可以确保在通过基类指针删除派生类对象时...当基类指针指向派生类对象时,如果删除对象时基类的析构函数不是虚函数,那么调用的仅仅是基类的析构函数,而不会调用派生类的析构函数。这样,派生类中分配的资源就无法释放,导致内存泄漏或其他资源管理问题。...,不调用 Derived 的析构函数 return 0; } 输出 Base destructor called 解释:在删除obj时,由于基类的析构函数不是虚函数,因此只调用了Base的析构函数...2.4.3 虚析构函数的注意事项 虚析构函数的必要性:任何含有虚函数的基类都应定义虚析构函数,以确保派生类对象通过基类指针删除时能够正确析构。...() {} // 提供析构函数体 总结 虚析构函数确保通过基类指针删除派生类对象时正确调用派生类的析构函数,避免内存泄漏。

    15710

    【C++指南】类和对象(三):类的默认成员函数——全面剖析: 析构函数

    引言 在C++编程中,析构函数是一个特殊的成员函数,它在对象的生命周期结束时被自动调用,用于执行清理工作,如释放对象占用的资源、关闭文件、解除动态分配的内存等。...还需要注意的是: 我们显式写析构函数,对于⾃定义类型成员也会调用他的析构,也就是说⾃定义类 型成员⽆论什么情况都会⾃动调⽤析构函数 析构函数的规则 只能有一个析构函数:每个类只能有一个析构函数。...成员对象的析构:当一个对象被销毁时,它的成员对象(包括基类部分)的析构函数会按照它们被构造的相反顺序被调用。...有资源申请时,⼀定要自己写析构,否则会造成资源泄漏 示例代码: 以下是一个简单的C++类,它包含动态分配的内存,并在析构函数中释放这些内存: #include class...调用成员对象的析构函数:如果对象包含其他对象作为成员,析构函数将自动调用这些成员对象的析构函数(按照成员变量在类中声明的逆序)。

    19910
    领券