#ifndef TESTAUTOFREE_CAUTOFREE_H
#define TESTAUTOFREE_CAUTOFREE_H
#include <iostream>
using namespace std;
// To free the instance in the current scope, for instance, MyClass* ptr,
// which is a ptr and this class will:
// 1. free the ptr.
// 2. set ptr to NULL.
//
// Usage:
// MyClass* po = new MyClass();
// // ...... use po
// SrsAutoFree(MyClass, po);
//
// Usage for array:
// MyClass** pa = new MyClass*[size];
// // ....... use pa
// SrsAutoFreeA(MyClass*, pa);
//
// @remark the MyClass can be basic type, for instance, SrsAutoFreeA(char, pstr),
// where the char* pstr = new char[size].
// To delete object.
#define CAutoFree(className, instance) \
impl_CAutoFree<className> _auto_free_##instance(&instance, false, false)
// To delete array.
#define CAutoFreeA(className, instance) \
impl_CAutoFree<className> _auto_free_array_##instance(&instance, true, false)
// Use free instead of delete.
#define CAutoFreeF(className, instance) \
impl_CAutoFree<className> _auto_free_##instance(&instance, false, true)
// The template implementation.
template<class T>
class impl_CAutoFree
{
private:
T** ptr;
bool is_array;
bool _use_free;
public:
// 禁止拷贝
impl_CAutoFree(const impl_CAutoFree&) = delete;
impl_CAutoFree& operator=(const impl_CAutoFree&) = delete;
// If use_free, use free(void*) to release the p.
// Use delete to release p, or delete[] if p is an array.
impl_CAutoFree(T** p, bool array, bool use_free) {
ptr = p;
is_array = array;
_use_free = use_free;
}
virtual ~impl_CAutoFree() {
if (ptr == NULL || *ptr == NULL) {
return;
}
if (_use_free) {
printf("~impl_CAutoFree ~~ use_free\n");
free(*ptr);
} else {
if (is_array) {
printf("~impl_CAutoFree ~~ use_delete[]\n");
delete[] *ptr;
} else {
printf("~impl_CAutoFree ~~use delete\n");
delete *ptr;
}
}
*ptr = NULL;
}
};
#endif //TESTAUTOFREE_CAUTOFREE_H