内存管理
内存管理一直是令C++程序员最头疼的工作,C++继承了C的那种高效而又灵活的指针,使用起来稍微不小心就会导致内存泄露,“野”指针,访问越界等问题。曾几何时,C++程序员曾经无限的向往Java,C#等语言的垃圾回收机制。虽然C++标准提供了智能指针std::auto_ptr,但并没有解决所有问题。
计算机系统中资源有很多种,内存是我们最常用到的,此外还有文件描述符,socket,操作系统handle,数据库连接等等,程序中申请这些资源后必须及时归还系统,否则就会产生难以预料的后果。
智能指针
智能指针的原理基于一个常见的习语叫做RAII:资源申请即初始化。智能指针只是这个习语的其中一例——当然是相当重要的一例。智能指针确保在任何情况下,动态分配的内存都能得到正确释放,从而将开放人员从这项任务重解放了出来。这包括程序因为异常而中断,原本用于释放内存的代码被跳过的场景。用一个动态分配的对象地址来初始化智能指针,在析构的时候释放内存,就确保了这一点。因为析构函数总是会被执行的,这样所包含的内存也将总是会被释放。
1998年修订的第一版C++标准只提供了一种智能指针:std::auto_ptr。它基本上就像是个普通的指针:通过地址来访问一个动态分配的对象。std::auto_ptr之所以被看作是智能指针,是因为它会在析构的时候调用delete操作符来自动释放所包含的对象。当然这要求在初始化得时候,传给它一个由new操作符返回的对象的地址。既然std::auto_ptr的析构函数会调用delete操作符,它所包含的对象的内存会确保释放掉。这是智能指针的一个优点。
实例
#include <stdio.h>
#include <stdlib.h>
//定义一个支持各种指针类型的模板
template <typename T>class MemHandler
{
private: T* _t;
public:
MemHandler():_t(NULL){}
MemHandler(T* t):_t(t){}
~MemHandler(){if (_t!=NULL) delete _t; }
};
class Test
{
public:
Test(){printf("Test construct\n");}
~Test(){printf("~ test destroyed\n");}
};
void main()
{
MemHandler<int>handle1(new int);
MemHandler<Test> handle2(new Test);
}
输出结果: