C++中的virtual析构函数创建时机(7)---《Effective C++》
2017-07-18 21:02
190 查看
条款7:为多态基类声明virtual析构函数
学习了上篇博客中所讲的virtual关键字之后,我们可以发现virtual关键字对于实现C++的多态至关重要,那么有一个新的问题,我们可以发现有时候我们为一个类声明虚析构函数,有的时候则并没有声明虚析构函数,那么什么时候我们声明,什么时候并不声明虚析构函数呢?正如如下代码所表现的那样:
在这个函数中我们并没有将基类的析构函数声明为virtual函数,那么到底是对的还是错的呢?
我们可以看到,b是一种A类型的指针,指向A的派生类B的一个对象,这时B中的z其实并没有被销毁,进而引发内存泄露、资源浪费等一系列严重的问题,那么如何解决这个问题呢?答案就是将基类A的析构函数声明为虚析构函数,即
这里有一些特例,需要掌握的,暂且当做补充吧!例如标准库中的string和STL容器,都没有虚析构函数,如果我们让某个类继承上述这种类,然后通过指针访问,删除指针的时候也将引发错误,如:
总结如下:
1.在基类中如果存在1个或者以上的虚函数,那么我们就需要将其析构函数声明为虚析构函数,因为如果不将其声明为析构函数,则会出现“局部销毁”,进而引发内存泄露等一系列问题;
2.如果类的设计目的是作为基类使用,则也应该声明为虚析构函数;
学习了上篇博客中所讲的virtual关键字之后,我们可以发现virtual关键字对于实现C++的多态至关重要,那么有一个新的问题,我们可以发现有时候我们为一个类声明虚析构函数,有的时候则并没有声明虚析构函数,那么什么时候我们声明,什么时候并不声明虚析构函数呢?正如如下代码所表现的那样:
在这个函数中我们并没有将基类的析构函数声明为virtual函数,那么到底是对的还是错的呢?
#include <iostream> #include <cstring> #include <string> using namespace std; class A{ public: A(int ii, int jj){ i = ii; j = jj; } virtual void show(){ cout <<"我是A中的show():"<< i << " " <<j<< endl; } ~A(){ } private: int i, j; }; class B :public A{ public: B(); B(int i, int j, int z) :A(i, j), z(z){ } void show(){ cout << "我是B中的show():"; A::show(); cout << z << endl; } private: int z; }; int main(){ A* b = new B(1, 2, 3); b->show(); delete b; return 0; 4000 }
我们可以看到,b是一种A类型的指针,指向A的派生类B的一个对象,这时B中的z其实并没有被销毁,进而引发内存泄露、资源浪费等一系列严重的问题,那么如何解决这个问题呢?答案就是将基类A的析构函数声明为虚析构函数,即
存在多态(基类函数中至少含有一个virtual)的类系统中(即类的继承中)中我们需要将基类的析构函数声明为virtual;
那么是不是什么情况下我们都应该将函数的析构函数声明为析构函数呢?答案并不是这样。如果一个类不含virtual函数,令其析构函数为虚函数往往是个坏主意,因为析构函数的存储特点,使得代码无法移植,因此,无端将所有类的析构函数声明为virtual,就像从未将其声明为virtual一样,都是错误的。这里有一些特例,需要掌握的,暂且当做补充吧!例如标准库中的string和STL容器,都没有虚析构函数,如果我们让某个类继承上述这种类,然后通过指针访问,删除指针的时候也将引发错误,如:
class stringSelf:public string{ ... }; stringSelf * ss=new StringSelf("hello"); string *ps; ps=ss; delete ps;//*ps的资源被泄露,因为stringSelf的析构函数没有被调用
总结如下:
1.在基类中如果存在1个或者以上的虚函数,那么我们就需要将其析构函数声明为虚析构函数,因为如果不将其声明为析构函数,则会出现“局部销毁”,进而引发内存泄露等一系列问题;
2.如果类的设计目的是作为基类使用,则也应该声明为虚析构函数;
相关文章推荐
- C++之创建自定义类型的数组---补充(17)《Effective C++》
- 虚拟现实-VR-UE4-创建第一个C++项目——Hello word
- c++ 循环创建不同名的txt
- session的创建时机
- Box2D C++教程4-创建测试
- windows怎么用C++创建文件夹,怎么用c++新建目录
- C++中创建、初始化以及删除 以变量为大小的动态二维数组
- C++也来操作线程之JNI线程创建
- Effective C++:条款4:尽量使用c++风格的注释
- C++之创建对象时的new与不new
- 不可或缺 Windows Native (19) - C++: 对象的动态创建和释放, 对象的赋值和复制, 静态属性和静态函数, 类模板
- C/C++ 创建线程解析
- C++动态创建二维数组
- 单链表的创建、打印、测试长度(基本操作)-C++
- 创建和使用动态链接库 (C++)
- C++中多语句创建“类成员变量”
- 【语言-C++】C++、C 创建挂起进程
- C++创建一个新的进程
- C++ 创建一个不能被继承的类
- [C++学习笔记14]动态创建对象(定义静态方法实现在map查找具体类名对应的创建函数,并返回函数指针,map真是一个万能类)good