Destruction aids memory management in object-oriented C Matthew Curreri Embedded Systems Programming October 2003 Listings Listing 1: The CApp class and main typedef struct _CApp { CWndNav *m_pWndNav; } CApp; void main(void) { unsigned int wParam; CApp * pApp; pApp = (CApp *) malloc(sizeof(CApp)); pApp->m_pWndNav = (CWndNav *) malloc(sizeof(CWndNav)); pApp->m_pWndNav->New = mWndNavNew; pApp->m_pWndNav->New(pApp->m_pWndNav); while (1) { int nChoice; printf("Press 1 = View 1\n"); printf(" 2 = View 2\n"); printf(" 3 = Exit\n"); scanf("%d", &nChoice); switch (nChoice) { case 1: wParam = ID_OPTION1; break; case 2: wParam = ID_OPTION2; break; default: return; } pApp->m_pWndNav->SendMessage(pApp->m_pWndNav, 0, wParam, 0L); } }; Listing 2 The CWndNav class */typedef struct _CWndNav { CWndView *m_pobjWndView; void (*Construct) (struct _CWndNav * _this); void (*Destruct) (struct _CWndNav * _this, CWndView *pobjWndNav); void (*SendMessage) (struct _CWndNav * _this, unsigned int Msg, unsigned int wParam, long lParam); void (*New) (struct _CWndNav * _this); } CWndNav; void mWndNavConstructor(CWndNav * _this) { _this->m_pobjWndView = (CWndView *) malloc(sizeof(CWndView)); _this->m_pobjWndView->New = mWndViewNew; // Assign new functional pointer _this->m_pobjWndView->New(_this->m_pobjWndView); _this->m_pobjWndView->Construct(_this->m_pobjWndView); }; void mWndNavDestructor(CWndNav * _this, CWndView *pobjWndNav) { pobjWndNav->Destruct(pobjWndNav); free(pobjWndNav); } void mWndNavWndProc(CWndNav * _this, unsigned int Msg, unsigned int wParam, long lParam) { switch (wParam) { case ID_OPTION1: _this->New(_this); _this->Construct(_this); _this->m_pobjWndView->SendMessage(_this->m_pobjWndView, 0, wParam, (long)"View 1" ); _this->Destruct(_this, _this->m_pobjWndView); break; case ID_OPTION2: _this->New(_this); _this->Construct(_this); _this->m_pobjWndView->SendMessage(_this->m_pobjWndView, 0, wParam, (long)"View 2" ); _this->Destruct(_this, _this->m_pobjWndView); break; } } void mWndNavNew(CWndNav * _this) { _this->Construct = mWndNavConstructor; _this->Destruct = mWndNavDestructor; _this->SendMessage = mWndNavWndProc; } Listing 3 The CButton and CWndView classes #include #include #include #define ID_OPTION1 0 #define ID_OPTION2 1 typedef struct _CButton { void (*Construct)(struct _CButton * _this); void (*Paint) (struct _CButton * _this, char * strCaption, int nLineNumber); void (*GotFocus) (struct _CButton * _this, char * strCaption, int nLineNumber); void (*New) (struct _CButton * _this); } CButton; void mButtonConstructor(CButton * _this) { // assignment of resources ‹ } void mButtonPaint(CButton * _this, char * strCaption, int nLineNumber) { switch (nLineNumber) { case 0: printf(" _________ "); break; case 1: printf("( )"); break; case 2: printf("( %s )", strCaption); break; case 3: printf("(_________)"); break; } } void mButtonGotFocus(CButton * _this, char * strCaption, int nLineNumber) { switch (nLineNumber) { case 0: printf(" "); break; case 1: printf("(*********)"); break; case 2: printf("(*%s*)", strCaption); break; case 3: printf("(*********)"); break; } } void mButtonNew(CButton * _this) { _this->Construct = mButtonConstructor; _this->Paint = mButtonPaint; _this->GotFocus = mButtonGotFocus; _this->New = mButtonNew; } typedef struct _CWndView { CButton *m_pButton; void (*Construct) (struct _CWndView * _this); void (*Destruct) (struct _CWndView * _this); void (*SendMessage) (struct _CWndView * _this, unsigned int Msg, unsigned int wParam, long lParam); void (*New) (struct _CWndView * _this); } CWndView; void mWndViewConstructor(CWndView * _this) { // assignment of resources ‹ } void mWndViewDestructor(CWndView * _this) { free(_this->m_pButton); } void mWndViewWndProc(CWndView * _this, unsigned int Msg, unsigned int wParam, long lParam) { switch (wParam) { case ID_OPTION1: _this->m_pButton->GotFocus(_this->m_pButton, "Option1", 0); printf(" _____________________________\n"); _this->m_pButton->GotFocus(_this->m_pButton, "Option1", 1); printf("( )\n"); _this->m_pButton->GotFocus(_this->m_pButton, "Option1", 2); printf("( )\n"); _this->m_pButton->GotFocus(_this->m_pButton, "Option1", 3); printf("( %s )\n", (char *) lParam); _this->m_pButton->Paint(_this->m_pButton, "Option2", 0); printf("( )\n"); _this->m_pButton->Paint(_this->m_pButton, "Option2", 1); printf("( )\n"); _this->m_pButton->Paint(_this->m_pButton, "Option2", 2); printf("( )\n"); _this->m_pButton->Paint(_this->m_pButton, "Option2", 3); printf("(_____________________________)\n\n\n"); break; case ID_OPTION2: _this->m_pButton->Paint(_this->m_pButton, "Option1", 0); printf(" _____________________________\n"); _this->m_pButton->Paint(_this->m_pButton, "Option1", 1); printf("( )\n"); _this->m_pButton->Paint(_this->m_pButton, "Option1", 2); printf("( )\n"); _this->m_pButton->Paint(_this->m_pButton, "Option1", 3); printf("( %s )\n", (char *)lParam); _this->m_pButton->GotFocus(_this->m_pButton, "Option2", 0); printf("( )\n"); _this->m_pButton->GotFocus(_this->m_pButton, "Option2", 1); printf("( )\n"); _this->m_pButton->GotFocus(_this->m_pButton, "Option2", 2); printf("( )\n"); _this->m_pButton->GotFocus(_this->m_pButton, "Option2", 3); printf("(_____________________________)\n\n\n"); break; } } void mWndViewNew(CWndView * _this) { _this->m_pButton = (CButton *) malloc(sizeof(CButton)); _this->m_pButton->New = mButtonNew; // Assign new functional pointer _this->m_pButton->New(_this->m_pButton); _this->Construct = mWndViewConstructor; _this->Destruct = mWndViewDestructor; _this->SendMessage = mWndViewWndProc; }