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

【日常】C++ 的那些“坑” —— delete 与 析构函数 与 virtual 的 9 个小例子

2017-04-28 13:09 447 查看
C++中有无数的坑,但毕竟……

今天就踩到了,也算是基本问题了,记录一下,顺便以后可以考考自己。你也可以猜猜答案,大牛绕行。

0x1 先看这个:

1 #include <stdio.h>
2 #include <stdlib.h>
3
4 class App
5 {
6 public:
7     ~App()
8     {
9         printf("\n~App\n");
10     }
11     void output()
12     {
13         printf("A");
14     }
15 };
16
17 class Bpp : public App
18 {
19 public:
20     ~Bpp()
21     {
22         printf("\n~Bpp\n");
23     }
24     void output()
25     {
26         printf("B");
27     }
28 };
29
30 int main(char args[])
31 {
32     Bpp* b = new Bpp();
33     delete b;
34
35     system("pause");
36     return 0;
37 }


结果:

~Bpp

~App
请按任意键继续. . .


0x02 : 再来 ,改了第32行

1 #include <stdio.h>
2 #include <stdlib.h>
3
4 class App
5 {
6 public:
7     ~App()
8     {
9         printf("\n~App\n");
10     }
11     void output()
12     {
13         printf("A");
14     }
15 };
16
17 class Bpp : public App
18 {
19 public:
20     ~Bpp()
21     {
22         printf("\n~Bpp\n");
23     }
24     void output()
25     {
26         printf("B");
27     }
28 };
29
30 int main(char args[])
31 {
32     App* b = new Bpp();
33     delete b;
34
35     system("pause");
36     return 0;
37 }


结果:

~App
请按任意键继续. . .


0x03 下一个 改动 7 line

1 #include <stdio.h>
2 #include <stdlib.h>
3
4 class App
5 {
6 public:
7     virtual ~App()
8     {
9         printf("\n~App\n");
10     }
11     void output()
12     {
13         printf("A");
14     }
15 };
16
17 class Bpp : public App
18 {
19 public:
20     ~Bpp()
21     {
22         printf("\n~Bpp\n");
23     }
24     void output()
25     {
26         printf("B");
27     }
28 };
29
30 int main(char args[])
31 {
32     App* b = new Bpp();
33     delete b;
34
35     system("pause");
36     return 0;
37 }


结果:

~Bpp

~App
请按任意键继续. . .


0x04 next 改动 line 20

1 #include <stdio.h>
2 #include <stdlib.h>
3
4 class App
5 {
6 public:
7     virtual ~App()
8     {
9         printf("\n~App\n");
10     }
11     void output()
12     {
13         printf("A");
14     }
15 };
16
17 class Bpp : public App
18 {
19 public:
20     virtual ~Bpp()
21     {
22         printf("\n~Bpp\n");
23     }
24     void output()
25     {
26         printf("B");
27     }
28 };
29
30 int main(char args[])
31 {
32     App* b = new Bpp();
33     delete b;
34
35     system("pause");
36     return 0;
37 }


结果和 0x03一样:

~Bpp

~App
请按任意键继续. . .


0x05 接着 再在第7 行中 去掉 virtual

1 #include <stdio.h>
2 #include <stdlib.h>
3
4 class App
5 {
6 public:
7     ~App()
8     {
9         printf("\n~App\n");
10     }
11     void output()
12     {
13         printf("A");
14     }
15 };
16
17 class Bpp : public App
18 {
19 public:
20     virtual ~Bpp()
21     {
22         printf("\n~Bpp\n");
23     }
24     void output()
25     {
26         printf("B");
27     }
28 };
29
30 int main(char args[])
31 {
32     App* b = new Bpp();
33     delete b;
34
35     system("pause");
36     return 0;
37 }


结果:

在33行,程序报错,崩溃。

0x6 改动 32行:

1 #include <stdio.h>
2 #include <stdlib.h>
3
4 class App
5 {
6 public:
7     ~App()
8     {
9         printf("\n~App\n");
10     }
11     void output()
12     {
13         printf("A");
14     }
15 };
16
17 class Bpp : public App
18 {
19 public:
20     virtual ~Bpp()
21     {
22         printf("\n~Bpp\n");
23     }
24     void output()
25     {
26         printf("B");
27     }
28 };
29
30 int main(char args[])
31 {
32     void* b = new Bpp();
33     delete b;
34
35     system("pause");
36     return 0;
37 }


结果:执行成功。

请按任意键继续. . .


0x07 把所有 virtual 去掉

#include <stdio.h>
#include <stdlib.h>

class App
{
public:
~App()
{
printf("\n~App\n");
}
void output()
{
printf("A");
}
};

class Bpp : public App
{
public:
~Bpp()
{
printf("\n~Bpp\n");
}
void output()
{
printf("B");
}
};

int main(char args[])
{
void* b = new Bpp();
delete b;

system("pause");
return 0;
}


结果:

请按任意键继续. . .


0x08 加上所有 virtual :

1 #include <stdio.h>
2 #include <stdlib.h>
3
4 class App
5 {
6 public:
7     virtual ~App()
8     {
9         printf("\n~App\n");
10     }
11     void output()
12     {
13         printf("A");
14     }
15 };
16
17 class Bpp : public App
18 {
19 public:
20     virtual ~Bpp()
21     {
22         printf("\n~Bpp\n");
23     }
24     void output()
25     {
26         printf("B");
27     }
28 };
29
30 int main(char args[])
31 {
32     void* b = new Bpp();
33     delete b;
34
35     system("pause");
36     return 0;
37 }


结果:

请按任意键继续. . .


0x09 最后:

1 #include <stdio.h>
2 #include <stdlib.h>
3
4 class App
5 {
6 public:
7     ~App()
8     {
9         printf("\n~App\n");
10     }
11     void output()
12     {
13         printf("A");
14     }
15 };
16
17 class Bpp : public App
18 {
19 public:
20     virtual ~Bpp()
21     {
22         printf("\n~Bpp\n");
23     }
24     void output()
25     {
26         printf("B");
27     }
28 };
29
30 int main(char args[])
31 {
32     Bpp* b = new Bpp();
33     delete b;
34
35     system("pause");
36     return 0;
37 }


结果,可以猜猜:

1 ~Bpp
2
3 ~App
4 请按任意键继续. . .


最后的答案

结语:

1. 通常应该给基类提供一个虚析构函数,即使它不需要析构函数 —— 《C++ Primer Plus (第6版)中文版》, 505页

2. 如果一个类带有任何 virtual 函数,这个类就应该拥有 virtual 析构函数 —— 《Effective C++ 中文版,第三版》,条款07:为多态基类声明 virtual 析构函数,44页

3. 如果一个类被当作基类(也就是说这个类需要被其他类继承),那这个类的析构函数就要加上 virual 关键字!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: