// main.h #ifndef _MAIN_H #define _MAIN_H typedef struct _AdvTemplate AdvTemplate; struct _AdvTemplate { char acAdvSubject[50]; char acAdvContext[50]; char* (*getAdvSubject)(AdvTemplate *pAdvTemplate); char* (*getAdvContext)(AdvTemplate *pAdvTemplate); void (*DeleteAdvTemplate)(AdvTemplate *pAdvTemplate); }; typedef struct _Mail Mail; struct _Mail { char receiver[20]; char subject[50]; char appellation[20]; char context[50]; char tail[20]; AdvTemplate *pAdvTemplate; Mail*(*CloneMail)(Mail *pMail); char* (*getReceiver)(Mail *pMail); void (*setReceiver)(char *pString,Mail *pMail); void (*setAppellation)(char *pString,Mail *pMail); void (*setTail)(char *pString,Mail *pMail); void (*DeleteMail)(Mail *pMail); }; #endif // main.h #include <stdio.h> #include <stdlib.h> #include <string.h> #include "main.h" char* getAdvSubject(AdvTemplate *pAdvTemplate) { return pAdvTemplate->acAdvSubject; } char* getAdvContext(AdvTemplate *pAdvTemplate) { return pAdvTemplate->acAdvContext; } void DeleteAdvTemplate(AdvTemplate *pAdvTemplate) { if(pAdvTemplate != NULL) { free(pAdvTemplate); pAdvTemplate=NULL; } } AdvTemplate *CreateAdvTemplate(void) { AdvTemplate *pAdvTemplate = (AdvTemplate*)malloc(sizeof(AdvTemplate)); if(!pAdvTemplate) { return NULL; } memset(pAdvTemplate,0,sizeof(AdvTemplate)); strcpy(pAdvTemplate->acAdvSubject,"This is subject"); strcpy(pAdvTemplate->acAdvContext,"This is context"); pAdvTemplate->getAdvSubject=getAdvSubject; pAdvTemplate->getAdvContext=getAdvContext; pAdvTemplate->DeleteAdvTemplate=DeleteAdvTemplate; return pAdvTemplate; } char* getReceiver(Mail *pMail) { return pMail->receiver; } void setReceiver(char* pString,Mail *pMail) { if(pString) { strcpy(pMail->receiver,pString); } } void setAppelltion(char* pString,Mail *pMail) { if(pString) { strcpy(pMail->appellation,pString); } } void setTail(char *pString,Mail *pMail) { if(pString) { strcpy(pMail->tail,pString); } } // 指向和預留空間的區別是什麼. Mail *CloneMail(Mail *pMail) { Mail *pCloneMail = (Mail*)malloc(sizeof(Mail)); if(pCloneMail) { memcpy(pCloneMail,pMail,sizeof(Mail)); } return pCloneMail; } /** 注意釋放的過程, 先釋放父類上的內容, 在釋放當前. 須要與free操做作對比測試. **/ void DeleteMail(Mail *pMail) { if(pMail->pAdvTemplate) { pMail->pAdvTemplate->DeleteAdvTemplate(pMail->pAdvTemplate); } if(pMail) { free(pMail); pMail = NULL; } } Mail *CreateMail(void) { Mail *pMail = (Mail *)malloc(sizeof(Mail)); if(!pMail) { return NULL; } memset(pMail, 0, sizeof(Mail)); pMail->pAdvTemplate = CreateAdvTemplate(); if(!pMail->pAdvTemplate) { return NULL; } pMail->setAppellation = setAppelltion; pMail->setReceiver = setReceiver; pMail->setTail = setTail; pMail->getReceiver = getReceiver; pMail->DeleteMail = DeleteMail; pMail->CloneMail = CloneMail; strcpy(pMail->context,pMail->pAdvTemplate->acAdvContext); strcpy(pMail->subject,pMail->pAdvTemplate->acAdvSubject); return pMail; } char *GetAppell() { return "abc"; } char *GetReceiver() { return "abc"; } void sendMail(Mail *pMail,int i) { printf("=======================================\r\n"); printf("receiver:%d---%s\r\n",i,pMail->getReceiver(pMail)); printf("subject:%s\r\n",pMail->subject); printf("appellation:%s\r\n",pMail->appellation); printf("context:%s\r\n",pMail->context); printf("=======================================\r\n"); } int main() { int max_count = 6; /*發送信件的數量*/ int i=1; Mail *pMail = NULL; Mail *pCloneMail = NULL; pMail = CreateMail(); pMail->setTail("xxx copyright.", pMail); while(max_count) { max_count--; /*克隆出一封Mail*/ pCloneMail = pMail->CloneMail(pMail); /*設置每封Mail的不一樣部分*/ pCloneMail->setAppellation(GetAppell(), pCloneMail); pCloneMail->setReceiver(GetReceiver(), pCloneMail); /*發送郵件*/ sendMail(pCloneMail,i); //pCloneMail->DeleteMail(pCloneMail); // 此處不要調用DeleteMail()操做, 主要的緣由是由於父類中的內會被修改.致使克隆的數據不可用. // free只釋放克隆時申請的空間, 不修改父類中的的信息. 是的程序服務調用父類中 的釋放操做. free(pCloneMail); i++; } pMail->DeleteMail(pMail); return 0; }