您的位置:首页 > 编程语言 > C语言/C++

c++之——虚析构函数

2017-03-11 11:55 218 查看
先看代码:

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     }




这样就没有内存泄漏了。

知识简要:

如果基类的析构函数不是虚函数,则delete一个指向派生类对象的基类指针将产生未定义的行为。之前我们介绍过一个准则,如果一个类需要析构函数,那么它同样需要拷贝和赋值操作。基类的析构函数并不遵循上述准则,它是一个重要的例外。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: