Developing Yed objects - The destructor

The aim of destructor is the right deallocation of an object. In Yed scenario, this means releasing all dynamic memory managed by the object, and then the object itself. As the constructor, the destructor of an object must be explicitly invoked when the instance is no longer needed.
The characteristics of its interface are:

In our example, the destructor's interface and first implementation are in red:

#include "yedstd.h"
#include "myclass.h"

MyClass * _MyClass(void) {
MyClass *this=malloc(sizeof(MyClass));
if(this!=NULL) {
  memset(this,0,sizeof(MyClass));
  this->My_Func=My_Func;
  this->PRIVATE(protected)=24;
  }
return this;
}

void _DMyClass(void *pvT) {
........
}


int My_Func(void *pVWork) {
MyClass *this=pvWork;        // 'THIS' POINTER OF THE INSTANCE!!!
printf("The protected member value is [%d]\n", this->PRIVATE(protected));
return 0;
}

What about the implementation of the destructor ?
Clearly, all dynamic memory allocated within the cycle of life of an instance of an object must be released ( i.e., any private buffer allocated with a 'malloc' system call ), and then the object itself, allocated with a 'malloc' into the constructor, must be released.

The implementation of destructor in our example becomes:

#include "yedstd.h"
#include "myclass.h"

MyClass * _MyClass(void) {
MyClass *this=malloc(sizeof(MyClass));
if(this!=NULL) {
  memset(this,0,sizeof(MyClass));
  this->My_Func=My_Func;
  this->PRIVATE(protected)=24;
  }
return this;
}

void _DMyClass(void *pvT) {
free(pvT);
}


int My_Func(void *pVWork) {
MyClass *this=pvWork;        // 'THIS' POINTER OF THE INSTANCE!!!
printf("The protected member value is [%d]\n", this->PRIVATE(protected));
return 0;
}

We don't have any dynamic memory to be released, then we free the instance of the object through its pointer 'this', passed as parameter.

The destructor is complete. As the constructor, we can generalize the invocation of every Yed destructor using an appropriate interface and a macro defined in the header file yedstd.h. Let's see how:

/*************************************************
NOME : YEDSTD.H
*************************************************/

#ifndef YEDSTD
#define YEDSTD

/****************
MACRO DEFINITION
****************/

#define PUBLIC
#define PRIVATE(x) __P##x

#define PRIVATE_FUNCTION static

/**** DYNAMIC CONSTRUCTOR AND DESTRUCTOR ****/

#define New(x) (x *)_##x()
#define Delete(x,a) _D##x(a)

/****************/

#endif

Look at the red line: this macro generalize invocation of Yed object destructors, as long as they have properly interface. How ?
C preprocessor substitutes every string 'Delete(x,a)' with the string '_Dx(a)'. The token '##' means concatenation of string in preprocessing of C source code.
So, if we write:

Delete(MyClass,this);

the output of C preprocessor will be:

_DMyClass(this);

that is, the invocation of the destructor of MyClass object.
Through the macro 'Delete(x,a)', we can use the same invocation for every Yed destructor. But it's very important that the destructor has the properly interface, else we must explicitly call the destructor in releasing object without using the macro.

The application using MyClass object becomes finally:

#include "yedstd.h"
#include "myclass.h"

main(){
MyClass *myClassInstance;

myClassInstance=New(MyClass);
if(myClassInstance!=NULL) {
  myClassInstance->My_Func(myClassInstance);
  }

Delete(MyClass,myClassInstance);

}


http://yed.sourceforge.net