【你问我答】C++什么时候要用虚析构函数?

问题描述:     

C++什么时候要用虚析构函数?

回答有奖:     

选取一位认真回答问题的牛友,赠送200牛币!
▶回答尽量有自己的思考,不要单纯的只是复制粘贴定理定义,或者他人blog哦~
    
你问我答问题汇总:点击进入
关注你问我答栏目:点击关注

你问我答 - 答问题,成大佬,拿牛币!
你问我答是牛客新栏目,每周1期几个问题,
牛友在问题贴下留下自己的知识,经验与见解,
帮助更多牛友了解更多技术相关知识!
#悬赏##C/C++#
全部评论
当使用到多态的时候,基类指针指向派生类对象。这时候析构对象,希望调用的是派生类的析构函数,如果没有定义虚析构函数的话,析构时只能调基类的析构函数。
1 回复
分享
发布于 2019-12-03 16:34
1.不会用作基类的类是不需要虚析构函数。 2.如果会使用基类指针并delete,那么需要使用虚析构函数,即使类里没有任何成员函数,否则delete会产生内存泄漏
1 回复
分享
发布于 2019-12-03 16:57
阿里巴巴
校招火热招聘中
官网直投
这个是继承才产生的问题,比如A类是B类的父类,学生时代可能遇到可能的代码比较多的是: A *a=new B; 是一个父类指针指向子类开辟的空间,然后delete a的时候只会delete掉指针,不会delete掉指向的空间。 void func(A *a); 这里的func函数可以接受A类 对象指针也可以接受B类对象指针然后在func里面,所以通常简便处理,我们只会写这样一个函数去处理A类对象指针以及它所有的继承类,不然如果A有100个继承类,每个类都写一样的方法,继承还有什么用?仔细看如下代码: #include <iostream> #include <memory> #include <string> #include <thread> #include <vector> #include <mutex> #include <random> class A { public: A() { std::cout << "Construct A:" << std::endl; } virtual void print() { std::cout << "A:" << std::endl; } ~A() { std::cout << "~A:" << std::endl; } }; class B:public A { public: B() { std::cout << "Construct B:" << std::endl; } void print() { std::cout << "B:" << std::endl; } ~B() { std::cout << "~B:" << std::endl; } }; void func(A *a) { a->print(); } int main() { A *a = new A; A *b = new B; func(a); func(b); delete a; delete b; return 0; } 输出结果如下:由于A没有虚析构函数,B类构造了但是没能析构,这样的情况多了就会导致内存泄漏。类似的工作里面还会经常用std::vector<A*>来存储所有A类以及A类继承类的指针,那么一定要把所有的父类(A类)的析构函数设为虚析构函数。
1 回复
分享
发布于 2019-12-03 17:04
在动态绑定中,需要对引用对象析构时,如果不声明为虚函数,那么调用的将是基函数的析构。这样继承类中动态分配的内存可能无法释放,造成内存泄露
点赞 回复
分享
发布于 2019-12-03 16:38
实现运行时多态,保证调用正确的析构函数,避免资源泄露。
点赞 回复
分享
发布于 2019-12-03 19:02
比如 class t1 {int T1;}; class t2 :public t1 {int T2;}; signed main() {     A *a = new B();     delete a;     return 0; } 这样的一份代码。 很明显会造成内存泄漏。 分析报错。 new-delete-type-mismatch 分配了8字节,结果只删除了4字节,明显的内存泄漏。 于是虚析构函数横空出世。 有了虚析构函数后,delete操作会正确识别类的真正类型,从而不会删除错误。
点赞 回复
分享
发布于 2019-12-06 23:01
因为他不是Java
点赞 回复
分享
发布于 2019-12-07 00:59
// 析构可以是虚函数,假如不声明为虚函数,有什么危害?   // 场景--通过通过基类指针访问子类时候,如果声明了虚函数,可以触发析正确析构顺序:首先是当前的的类,然后是起基类。   // 如果没有有定义虚析构函数的话,属于静态绑定,只根据基类这个类型(this)调用对应函数。   //说明1 :场景--A通过基类通过引用访问,或者 通过子类访问 不会出现这样问题。正确触发析构   //说明2 ,先释放子类,在释放基类 ,这个表示不正确,// A B C  删除 B ,不会触发c的   // 基类不析构不声明为虚函数 通过自己调用,和引用调用 保持正常的修改,但是通过基类访问无法触发。这可能是是一个bug
点赞 回复
分享
发布于 2019-12-24 16:26

相关推荐

点赞 2 评论
分享
牛客网
牛客企业服务