c++之——虚析构函数

先看代码:

  1 #include<iostream>
  2 using namespace std;
  3
  4 class Parent {
  5 public:
  6     Parent() :a(100), b(200), c(300)
  7     {
  8
  9         p = new char[10];
 10         //strcpy(p, "abc");
 11         cout << "parent 无参构造。。。\n";
 12     }
 13     Parent(int test) :a(1000), b(2000), c(3000)
 14     {
 15         p = new char[10];
 16         //strcpy(p, "abc");
 17         cout << "parent 有参构造。。。\n";
 18     }
 19     ~Parent()
 20     {
 21         delete[] p;
 22         cout << "Parent 析构。。。\n";
 23     }
 24     int a;
 25     int b;
 26     int c;
 27     char *p;
 28     void p_print()
 29     {
 30         cout << "a b c is" << a << " " << b << " " << c << endl;
 31     }
 32
 33 };
 34 class Child1 :  public Parent
 35 {
 36 public:
 37     Child1() :Parent(1),a(10), b(0), c(0)
 38     {
 39         p = new char[10];
 40     //    strcpy(p, "abc");
 41         cout << "child1 构造\n";
 42     }
 43     ~Child1()
 44     {
 45         delete[] p;
 46         cout << "child1 析构,,,\n";
 47     }
 48     void c1_print()
 49     {
 50         cout << "a b c is" << a << " " << b << " " << c << endl;
 51     }
 52
 53     int a;
 54     int b;
 55     int c;
 56     char *p;
 57 };
 58 class Child2 :  public Child1
 59 {
 60 public:
 61     Child2() :Child1(), b(2), c(3)
 62     {
 63         p = new char[10];
 64         //strcpy(p, "abc");
 65         cout << "child2 构造\n";
 66     }
 67     ~Child2()
 68     {
 69         delete[] p;
 70         cout << "child2 析构,,,\n";
 71     }
 72     void c2_print()
 73     {
 74         cout << "a b c is" << Parent::a << " " << b << " " << c << endl;
 75     }
 76     //int a;
 77     int b;
 78     int c;
 79     char *p;
 80 };
 81 /*
 82 class Child3 : public Child1, public Child2
 83 {
 84 public:
 85     Child3() : Child1(), Child2(), b(20), c(30) { cout << "child 构造\n"; }
 86     ~Child3()
 87     {
 88         cout << "child 析构,,,\n";
 89     }
 90     void c3_print()
 91     {
 92         cout << "a b c is" << a << " " << b << " " << c << endl;
 93     }
 94     //int a;
 95     int b;
 96     int c;
 97 };
 98 */
 99 void play()
100 {
101     Child2* c2 = new Child2;
102     delete c2;
103 }
104 int main()
105 {
106     //Child2* c2 = new Child2;
107     play();
108     return 0;
109 }

这样是没问题的,但是,在很多时候,我们不能在调用函数末尾就delete掉这个内存,还需要和后续交互,所以更常见和一般的设计思维是更改paly和main函数如下:

 1 void play(Parent* p)
 2 {
 3     delete p;
 4 }
 5 int main()
 6 {
 7     Child2* c2 = new Child2;
 8     play(c2);
 9     return 0;
10 }

运行结果显示内存泄漏了,只析构了父类;所以我们有那么一种需求,要想和多态的效果一样,传什么指针去,自动析构应该析构的东西,更改代码,实现虚析构函数。

只用更改基类的析构函数,加上virtual关键字:

1     virtual ~Parent()
2     {
3         delete[] p;
4         cout << "Parent 析构。。。\n";
5     }

这样就没有内存泄漏了。

只是简要:

时间: 2024-08-11 07:48:39

c++之——虚析构函数的相关文章

第六篇:为多态基类声明虚析构函数

前言 在很多类中,可以看到其析构函数都是声明为虚函数的. 那么,为何要将析构函数声明为虚函数?哪些情况要将析构函数声明为虚函数? 本文将为你解惑. 在使用 C++ 实现多态的时候,有一点一定要清楚:当派生类对象经由基类指针被删除,而此基类的析构函数没有被声明为虚函数的话,那么析构函数只会释放基类部分的成员而无视派生类成员. 如果不对这一点加以防范,那么很多时候,会带来内存泄露这样灾难性的后果. 问题描述 假设,有以下几个类,分别代表:钟,原子钟,水钟,腕表: 1 // 钟 2 class Tim

C++虚析构函数

在类中,构造函数用于初始化对象及相关操作,构造函数是不能声明为虚函数的,因为在执行构造函数前对象尚未完成创建,虚函数表尚不存在,此时就无法去查询虚函数表,因此也就无法得知该调用哪一个构造函数了. 析构函数则用于销毁对象时完成相应的资源释放工作,析构函数可以被声明为虚函数.我们先通过一个例子来说明析构函数声明为虚函数的必要性. 例1: #include<iostream>using namespace std; class base{public: base(); ~base();private

虚析构函数(√)、纯虚析构函数(√)、虚构造函数(X)

from:http://blog.csdn.net/fisher_jiang/article/details/2477577 一. 虚析构函数 我们知道,为了能够正确的调用对象的析构函数,一般要求具有层次结构的顶级类定义其析构函数为虚函数.因为在delete一个抽象类指针时候,必须要通过虚函数找到真正的析构函数. 如: class Base{public:   Base(){}   virtual ~Base(){}};class Derived: public Base{public:   D

条款7:为多态的基类声明虚析构函数。

任何的类只要带有一个virtual函数那么就集合可以确定其应该有一个virtual析构函数. 同样的如果一个函数不含有virtual函数,那么通常意味着其不是一个基类函数,而且为一个不是基类的类声明virtual的析构函数是十分糟糕的事情,不要这样做.具体原因在下面: 1.首先,想要实现出virtual函数,对象必须要携带某些信息,.信息通过vptr来实现,这个vptr指向一个由函数指针构成的数组,即vtbl.盲目的去使用虚函数就会使得浪费资源.(一般人的经验是,只有当函数需要使用一个虚函数的时

C++中的虚析构函数、纯虚析构函数详解

C++中析构函数可以为纯虚函数吗? 众所周知,在实现多态的过程中,一般将基类的析构函数设为virtual,以便在delete的时候能够多态的链式调用.那么析构函数是否可以设为纯虚呢? class CBase { public: CBase() { printf("CBase()\n"); } virtual ~CBase() = 0; // 析构函数是纯虚函数 }; 答案是可以,那么这样实现的目的是什么呢?当然是避免实例化. 但因为派生类不可能来实现基类的析构函数,所以基类析构函数虽然

c++之虚析构函数

1.虚析构函数: 构造函数不能是虚函数.建立一个派生类对象时,必须从类     层次的根开始,沿着继承路径逐个调用基类的构造函数 析构函数可以是虚的.虚析构函数用于指引 delete 运算符正    确析构动态对象 2. 定义了基类虚析构函数,基类指针指向的 派生类动态对象也可以正确地用delete析构 3 设计类层次结构时,提供一个虚析构函数, 能够使派生类对象在不同状态下正确调用 析构函数 1 #include <iostream> 2 using namespace std; 3 4 c

关于虚析构函数的作用和使用

作用:作为基类使用的类应该具有虚析构函数,以保证在删除基类指针(动态分配的对象)时.依据指针实际指向的对象进行适当的析构. 请看以下这段代码; #include <iostream> class A{ public: A(){ std::cout << "A constructor execute" << std::endl; } ~A(){ std::cout << "A destructor execute" &l

虚析构函数

简单来说析构函数就是回收站.若系统不及时去回收这些垃圾(通常是无用的内存资源),那么时间越久肯定会有越来越多的垃圾.在开相同的程序,有时候手机和电脑重启了一下,速度会明显变快很多.因为RAM中的资源掉电后就释放了. 在C++中,析构函数就是释放无用资源的.在派生类中,假设用基类指针指向了一个派生类的临时变量.那么会发生什么情况.实际上这个时候只会释放基类的无用资源而没有释放这个临时的派生类的资源. #include<iostream> usingnamespacestd; classPoint

C++ Primer 学习笔记_34_面向对象编程(5)--虚函数与多态(二):纯虚函数、抽象类、虚析构函数、动态创建对象

C++ Primer 学习笔记_34_面向对象编程(5)--虚函数与多态(二):纯虚函数.抽象类.虚析构函数.动态创建对象 一.纯虚函数 1.虚函数是实现多态性的前提 需要在基类中定义共同的接口 接口要定义为虚函数 2.如果基类的接口没办法实现怎么办? 如形状类Shape 解决方法 将这些接口定义为纯虚函数 3.在基类中不能给出有意义的虚函数定义,这时可以把它声明成纯虚函数,把它的定义留给派生类来做 4.定义纯虚函数: class <类名> { virtual <类型> <函

虚析构函数(c++常问问题五)

当子类析构需要调用父类的析构函数,基类的析构函数必须设置为虚析构函数 //基类 class base { base() { cout<<"base "; } virtual ~base() { cout<<"~base "; } } //派生类 class cat : public base { cat () { cout<<"cat "; } virtual ~cat () { cout<<&qu