Winx基本类使用指南之C++标准扩展(AutoFreeAlloc)[注1]
在C++中,一般有两种内存分配的方式:
1. 传统的配对方式
Ø C++中的new与delete
Ø C中alloc与free
Ø Windows API中GlobalAlloc与GlobalFree、HeapAlloc与HeapFree等
这种分配方式首先一件事就是要记住在分配内存后一定要释放,这一点在吃过几次亏后总是能够记住;但是在某个程序段的分支或异常处理多起来时(并且这个程序段不止一次的分配内存),再使用这种内存分配方式就会头大如斗(我想,绝大多数的C++程序员都应该对此有所体会)。
2. 使用智能指针
使用智能指针可以解决传统的配对方式的问题,但同时却又引出了新的问题。智能指针品种很多,记住它们的各种规则更是困难。本人愚苯,每次使用boost库中的智能指针,总是先要去看它们的帮助文档。
现在终于有了第三种内存分配方式,这就是Winx中AutoFreeAlloc机能(这个机能属于Winx的标准C++的扩展部分),其基本原理是由一个AutoFreeAlloc负责某程序段中所有的内存分配,而不管所分配内存是由什么对象使用,在该程序段结束时,再由这个AutoFreeAlloc释放所有被分配的内存。对于具体的底层实现机制,感兴趣的朋友可以参照xushiwei的最袖珍的垃圾回收器。
下面就转入正题,介绍一下AutoFreeAlloc的使用方法及在使用中要注意的一些问题。
使用AutoFreeAlloc的例子
下面的例子主要演示了使用AutoFreeAlloc的一些方式(在main函数中),其主要功能是首先定义一个分配器,然后为一系列对象分配内存。
class ClassA
{
private:
int var_int_;
double var_double_;
public:
ClassA() { }
};
class ClassB
{
private:
int var_int_;
double var_double_;
public:
ClassB() : var_int_(0), var_double_(0.0) { }
ClassB(const ClassB& cb) :
var_int_(cb.var_int_), var_double_(cb.var_double_)
{}
~ClassB() { }
};
class ClassC
{
private:
int var_int_;
double var_double_;
ClassB class_b_;
public:
ClassC() { }
~ClassC() { }
};
int main()
{
AutoFreeAlloc alloc;
ClassA* ca = STD_NEW(alloc, ClassA);
ClassA* caArray = STD_NEW_ARRAY(alloc, ClassA, 100);
for (int i = 0; i < 100; ++i)
{
// print address of each element of Array caArray
cout << caArray + i << endl;
}
ClassB cbTemp;
// assign cbTemp to cb
ClassB* cb = STD_NEW(alloc, ClassB)(cbTemp);
ClassB* cbArray = STD_NEW_ARRAY(alloc, ClassB, 100);
ClassC* cc = STD_NEW(alloc, ClassC);
ClassC* ccArray = STD_NEW_ARRAY(alloc, ClassC, 100);
// assign 1 to i1
int* i1 = STD_NEW(alloc, int)(1);
int* i2 = STD_NEW_ARRAY(alloc, int, 100);
// assign 0.0 to d1
double* d1 = STD_NEW(alloc, double)(0.0);
double* d2 = STD_NEW_ARRAY(alloc, double, 100);
int* i3 = STD_ALLOC(alloc, int);
int* i4 = STD_ALLOC_ARRAY(alloc, int, 100);
double* d3 = STD_ALLOC(alloc, double);
double* d4 = STD_ALLOC_ARRAY(alloc, double, 100);
char* s1 = STD_NEW(alloc, char);
*s1 = 'T';
cout << *s1 << endl;
char* s2 = STD_NEW_ARRAY(alloc, char, 128);
strcpy(s2, "hello world!");
cout << s2 << endl;
char* s3 = STD_NEW(alloc, char);
char* s4 = STD_NEW_ARRAY(alloc, char, 128);
strcpy(s4, "hello world 2!");
cout << s4 << endl;
return 0;
}
通过上面的例子可以看出,AutoFreeAlloc的使用非常简单,只有2个步骤:
1. 定义AutoFreeAlloc
2. 通过STD_NEW、STD_NEW_ARRAY、STD_ALLOC、STD_ALLOC_ARRAY这4个宏中的一个来分配内存(或者说创建对象),这是不是有点象java中的new操作呢?J
内存分配器的定义
内存分配器的定义是用main函数中的第一条语句来完成的:
AutoFreeAlloc alloc;
这条语句很简单,但一些幕后的细节我们需要了解。我们再来看AutoFreeAlloc是有一个typedef来定义的:
typedef AutoFreeAllocT<StdLibAlloc> AutoFreeAlloc;
而StdLibAlloc的定义如下:
struct StdLibAlloc
{
static void* allocate(size_t cb)
{ return malloc(cb); }
static void* allocate(size_t cb, DestructorType fn)
{ return malloc(cb); }
static void* allocate(size_t cb, int fnZero)
{ return malloc(cb); }
static void deallocate(v