内存管理是C++最令人痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的性能,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在。难道使用C++就不能像使用C#或java那样,不管内存的释放吗?其实我们可以通过适当的设计来减轻我们对内存的管理任务。虽然不能像C#或java那样,完全不管内存的使用和释放,但是也能在很大程度上减轻我们对内存的管理压力。下面就以本人设计的一个基类说明一下,如何实现C++内存的半自动释放。至于为什么说是半自动释放,看完这篇文章你就会知道了,现在可以不必深究。
一、设计思想 我们知道,在C++中,当一个对象被释放时,它的析构函数必定会被调用,而如果该对象的类型是一个子类,则其先调用自己的析构函数,再调用其父类的析构函数。所以我们可以利用这个特性设计一个基类Object,它的责任就是负责释放它的子类申请的资源。而释放的操作,我们可以放在析构函数中。
在基类Object中保存一个链表childern,链表childern中的值是其new出来的对象的指针,我把该对象叫做父对象,由该对象new出来的对象叫做子对象,例如: A a; a.createObj(); 类A是基类Object的子类,对象a通过调用其成员函数createObj来创建了10个B类(也是Object的派生类)的对象,则a就是父对象,而那10个B类的对象就是子对象。当父对象析构时,就会调用Object的析构函数,从而会把它的所有子对象释放掉。也就是说,当a被释放时,就会调用Object类的析构函数,从而释放它new出来的10个子对象(B类的对象)。这样,就可以简化我们对内存的管理。
PS:这个实现机制是参考Qt的内存管理机制。
Object的头文件(object.h)如下:
#ifndef OBJECT_H #define OBJECT_H #includeusing std::list; class Object; typedef list
Object的实现文件(object.cpp)如下:
#include object.h #includeObject::Object(Object *parent) :this_parent(parent) { /*** 函数功能:创建一个Object对象,若其parent不为空, 则把当前对象插入到其子对象列表中 ***/ if(this_parent != NULL) this_parent->childern.push_back(this); } Object::Object(const Object& obj) { /*** 函数功能:根据对象obj,复制一个对象 ***/ //复制时,只是把当前对象和obj的父对象设置为同一个父对象 //并不复制obj的子对象列表 _appendObjectList(obj.this_parent); } Object& Object::operator= (const Object &obj) { /*** 函数功能:若当前对象无父对象,则把obj的父对象设置成当前对象的父对象 返回:当前对象的引用 ***/ if(this_parent == NULL) { _appendObjectList(obj.this_parent); } return *this; } Object::~Object() { /*** 函数功能:释放由该对象new出来的子对象 ***/ //若当前对象有父对象,则将当前对象从共父对象的子对象列表中删除 if(this_parent != NULL) { ObjectList::iterator it = find(this_parent->childern.begin(), this_parent->childern.end(), this); this_parent->childern.erase(it); // this_parent->childern.remove(this); } //释放其new出来的子对象 while(!childern.empty()) { ObjectList::iterator it(childern.begin()); delete *it; } } void Object::setParent(Object *parent) { /*** 函数功能:重新设置对象的父对象 返回:无 ***/ //若当前对象有父对象,则把当前对象从其父对象的子对象列表中删除 if(this_parent != NULL) { ObjectList::iterator it = find(this_parent->c