析构函数

c++ 虚析构函数的作用分析

末鹿安然 提交于 2019-12-07 07:17:55
1.为什么基类的析构函数是虚函数?    在实现多态时,当用基类指针操作派生类对象时,在析构时防止只析构基类而不析构派生类的状况发生。 什么是多态: 根据面向对象的继承规则,派生类跟基类是IS-A的关系。也就是说派生类的对象也是一个基类对象。所以基类的指针可以指向派生类的对象以便实现多态。(让基类实现多态) 亦即: 这样做是为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用; 下面看代码----------------------------------------------------------------------------------------------------------   a.第一段代码    #include<iostream> using namespace std; class ClxBase{ public : ClxBase() {}; ~ClxBase() {cout << " Output from the destructor of class ClxBase! " << endl;}; void DoSomething() { cout << " Do something in class ClxBase! " << endl; }; }; class ClxDerived : public ClxBase{

C++ 虚析构函数 纯虚析构函数 虚构造函数

南楼画角 提交于 2019-12-07 07:17:28
众所周知,在实现多态的过程中,一般将基类的析构函数设为virtual,以便在delete的时候能够多态的链式调用。那么析构函数是否可以设为纯虚呢? class CBase { public : CBase() { printf("CBase()\n"); } virtual ~CBase() = 0; }; 答案是可以,那么这样实现的目的是什么呢?当然是避免实例化。 但因为派生类不可能来实现基类的析构函数,所以 基类析构函数虽然可以标为纯虚,但是仍必须实现析构函数 ,否则派生类无法继承,也无法编译通过。 下面详细讨论: 一. 虚析构函数 我们知道,为了能够正确的调用对象的析构函数,一般要求具有层次结构的顶级类定义其析构函数为虚函数。因为在delete一个抽象类指针时候,必须要通过虚函数找到真正的析构函数。 如: [cpp] view plain copy print ? class Base { public : Base(){} virtual ~Base(){} }; class Derived: public Base { public : Derived(){}; ~Derived(){}; } void foo() { Base *pb; pb = new Derived; delete pb; } 这是正确的用法,会发生动态绑定,它会先调用Derived的析构函数

C++虚析构函数

我怕爱的太早我们不能终老 提交于 2019-12-07 07:16:48
C++的虚析构函数: 用C++开发的时候,用来做基类的类的析构函数一般都是虚函数。 这样做是为了当用一个基类的指针删除一个派生类的对象时,派生类的析构函数会被调用,如果析构函数不是虚拟的,则将只调用对应于指针类型的析构函数。当然,并不是要把所有类的析构函数都写成虚函数。因为当类里面有虚函数的时候,编译器会给类添加一个虚函数表,里面来存放虚函数指针,这样就会增加类的存储空间。所以,只有当一个类被用来作为基类的时候,才把析构函数写成虚函数。 下面来看一个实例: 父类Dad.cpp: #include <iostream> using namespace std; class Dad { public: Dad(){} ~Dad(){ cout<<"Dad's destructor"<<endl; } virtual void sayName() { cout<<"I am Dad."<<endl; } }; 子类Son.cpp: #include "Dad.cpp" class Son :public Dad { public: Son(){} void sayName() { cout<<"I am Son"<<endl; } ~Son() { cout<<"Son's destructor"<<endl; } }; int main() { Dad *obj1 = new Son(

再说c++虚析构函数

此生再无相见时 提交于 2019-12-07 07:16:34
关于c++类中的虚析构函数。我写这篇博客是为了得出如下3点结论。 1.所有基类的析构函数,都应该声明为虚析构函数!这也是c++标准所指定的。 2.如果设计一个类,可能会被后来的其他类所继承,我们一定要将它的析构函数声明为虚析构。否则被继承会出现内存泄漏等意想不到的问题。 3.如果我们要去继承另外一个类,首先一点是要保证被继承的类的析构函数已经声明为了虚析构函数! 对以上3点,如果你深有理会,如下内容可以不看,不要浪费时间。如果没有很深的概念,可以参考一下。如有问题,希望在评论区或其他方式给我指点,谢谢。 非继承类的析构函数执行会有如下操作 : 1、执行析构函数中的代码 2、如果所在类有成员变量(类对象),再执行类成员变量的析构函数 普通析构函数: 以如下代码为例 class Student { public : Student () { name = new char [ 32 ]; cout << "Student constructor new name char[32]" << endl; } ~ Student () { delete name ; cout << "Student destructor delete Student::name" << endl; } private : char * name ; }; class Normal { public :

C++中为什么需要将基类的析构函数设置为虚函数

半城伤御伤魂 提交于 2019-12-07 07:16:07
大家知道,析构函数是为了在对象不被使用之后释放它的资源,虚函数是为了实现多态。那么把析构函数声明为vitual有什么作用呢? 直接的讲,C++中基类采用virtual虚析构函数是为了防止内存泄漏。具体地说,如果派生类中申请了内存空间,并在其析构函数中对这些内存空间进行释放。假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就 不会触发动态绑定 ,因而只会调用基类的析构函数,而不会调用派生类的析构函数。那么在这种情况下,派生类中申请的空间就得不到释放从而产生内存泄漏。所以,为了防止这种情况的发生,C++中基类的析构函数应采用virtual虚析构函数。 # include <iostream> using namespace std ; class A { public : A ( ) { } ; //构造函数 ~ A ( ) { cout << "释放class A的内存" << endl ; } ; //析构函数 } ; class B : public A { public : B ( ) { } ; //构造函数 ~ B ( ) { cout << "释放class B的内存" << endl ; } ; //析构函数 } ; int main ( ) { //情况一: B * b = new B ( ) ; delete b ; cout << "-------

C++——基类的析构函数没有声明为虚函数造成的影响

北城余情 提交于 2019-12-07 07:15:37
C++明确指出,当派生类对象经由一个基类指针被删除,而该基类带着一个non-virtual析构函数(即非虚析构函数),其结果是未有定义的,实际在执行时通常会发生的是对象的派生成分没有被销毁(即派生类的析构函数没有执行),这样就造成基类成分被销毁了,但是派生类成分没有被销毁,于是造成了一个诡异的“局部销毁”对象,这样可能会形成资源泄漏、败坏之数据结构,在调试器上浪费很多时间进行调试。 来源: CSDN 作者: 鬼 | 刀 链接: https://blog.csdn.net/gaoyu1253401563/article/details/90600657

C++将多态基类的析构函数声明为virtual的作用

怎甘沉沦 提交于 2019-12-07 07:10:49
如果没有将多态基类的析构函数声明为virtual 当通过基类指针构造子类对象的时候,此时使用基类来引用/表示子类: BaseClass *b = new ChildClass; 如果析构函数不是virtual的,那么调用析构函数时: delete b; 这时,调用BaseClass的析构函数,进行析构;== 问题出现:使用基类的析构函数进行析构操作,但是实际对象却是这个基类的子类。所以,这样析构只能释放基类的部分,而子类的部分没有被释放(因为基类的析构函数并没有能力去析构子类的成员部分),造成内存泄露。 == 将多态基类的析构函数声明为virtual的目的 继续上面的例子,但是将BaseClass的析构函数定义为virtual。这时, delete b 仍然通过子类BaseClass来调用析构函数。== 但是,此时析构函数是virtual的,并且基类变量实际指向的是其子类对象,因此,发生动态绑定。 ==动态绑定的结果是, delete 调用的析构函数实际是子类的析构函数。这样,通过基类进行的析构操作成功地通过动态绑定调用了子类的析构函数,能够将子类的部分析构释放掉,避免内存泄露。 总结:将析构函数声明为virtual是为了激活动态绑定,用对应子类的析构函数来执行析构操作 任何class只要带有virtual函数都几乎确定应该也有一个virtual析构函数

虚析构函数

十年热恋 提交于 2019-12-07 07:10:21
直接的讲,C++中基类采用virtual虚析构函数是为了防止内存泄漏。 具体地说, 如果派生类中申请了内存空间 ,并在其 析构函数中 对这些内存空间进行 释放 。假设 基类 中采用的是 非虚析构函数 ,当delete 基类指针指向的派生类对象时 就不会触发 动态绑定 ,因而 只会调用基类的析构函数 ,而 不会调用派生类的析构函数 。那么在这种情况下, 派生类中申请的空间就得不到释放从而产生内存泄漏 。如果基类中析构函数声明为虚函数,则delete基类指针指向的派生类对象时通过动态绑定能够调用派生类的虚构函数,先执行派生类析构函数的函数体,再执行基类析构函数的函数体。所以,为了防止这种情况的发生,C++中基类的析构函数应采用virtual虚析构函数。 示例 基类析构函数未声明虚函数 #include <iostream> using namespace std; class Base { public: ~Base(){cout<<"~Base()"<<endl;} }; class Derived:public Base { public: virtual ~Derived(){cout<<"~Derived()"<<endl;} }; void test() { Base* b=new Derived(); delete b; cin.get(); } 输出

C++中基类的虚析构函数问题

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-07 07:10:12
c++中如果定义基类,要使用多态的话,基类的析构函数必须定义为虚函数,这样在析构的时候,资源才会回收干净,否则只会回收基类资源,而不会回收继承类资源。 来源: CSDN 作者: map-link 链接: https://blog.csdn.net/sj201012137044/article/details/48550973

C++中基类的析构函数为什么要用virtual虚析构函数

我怕爱的太早我们不能终老 提交于 2019-12-07 07:09:56
大家知道,析构函数是为了在对象不被使用之后释放它的资源,虚函数是为了实现多态。那么把析构函数声明为vitual有什么作用呢? 直接的讲, C++中基类采用virtual虚析构函数是为了防止内存泄漏。具体地说,如果派生类中申请了内存空间,并在其析构函数中对这些内存空间进行释放。假设基类中采用的是非虚析构函数,当删除基类指针指向的派生类对象时就不会触发动态绑定,因而只会调用基类的析构函数,而不会调用派生类的析构函数。那么在这种情况下,派生类中申请的空间就得不到释放从而产生内存泄漏。所以,为了防止这种情况的发生,C++中基类的析构函数应采用virtual虚析构函数。 请看下面的代码: #include <iostream> using namespace std; class Base { public: Base() {}; //Base的构造函数 ~Base() //Base的析构函数 { cout << "Output from the destructor of class Base!" << endl; }; virtual void DoSomething() { cout << "Do something in class Base!" << endl; }; }; class Derived : public Base { public: Derived() {}; /