OOP'un ne olduğunu bilmeden önce C'de bu tür şeyleri yapardım.
Aşağıda, minimum boyut, artış ve maksimum boyut göz önüne alındığında, talep üzerine büyüyen bir veri tamponu uygulayan bir örnek verilmiştir. Bu özel uygulama "eleman" tabanlıdır, yani, sadece değişken uzunluklu bir bayt-tamponu değil, herhangi bir C tipinin liste benzeri bir koleksiyonuna izin vermek üzere tasarlanmıştır.
Buradaki fikir, nesnenin xxx_crt () kullanılarak başlatılması ve xxx_dlt () kullanılarak silinmesidir. "Üye" yöntemlerinin her biri üzerinde çalışmak için özel olarak yazılmış bir işaretçi alır.
Bağlantılı bir liste, döngüsel tampon ve diğer bazı şeyleri bu şekilde uyguladım.
İtiraf etmeliyim, bu yaklaşımla kalıtımın nasıl uygulanacağı hakkında hiç bir fikir vermedim. Kieveli tarafından sunulan karışımın bazı karışımlarının iyi bir yol olabileceğini hayal ediyorum.
dtb.c:
#include <limits.h>
#include <string.h>
#include <stdlib.h>
static void dtb_xlt(void *dst, const void *src, vint len, const byte *tbl);
DTABUF *dtb_crt(vint minsiz,vint incsiz,vint maxsiz) {
DTABUF *dbp;
if(!minsiz) { return NULL; }
if(!incsiz) { incsiz=minsiz; }
if(!maxsiz || maxsiz<minsiz) { maxsiz=minsiz; }
if(minsiz+incsiz>maxsiz) { incsiz=maxsiz-minsiz; }
if((dbp=(DTABUF*)malloc(sizeof(*dbp))) == NULL) { return NULL; }
memset(dbp,0,sizeof(*dbp));
dbp->min=minsiz;
dbp->inc=incsiz;
dbp->max=maxsiz;
dbp->siz=minsiz;
dbp->cur=0;
if((dbp->dta=(byte*)malloc((vuns)minsiz)) == NULL) { free(dbp); return NULL; }
return dbp;
}
DTABUF *dtb_dlt(DTABUF *dbp) {
if(dbp) {
free(dbp->dta);
free(dbp);
}
return NULL;
}
vint dtb_adddta(DTABUF *dbp,const byte *xlt256,const void *dtaptr,vint dtalen) {
if(!dbp) { errno=EINVAL; return -1; }
if(dtalen==-1) { dtalen=(vint)strlen((byte*)dtaptr); }
if((dbp->cur + dtalen) > dbp->siz) {
void *newdta;
vint newsiz;
if((dbp->siz+dbp->inc)>=(dbp->cur+dtalen)) { newsiz=dbp->siz+dbp->inc; }
else { newsiz=dbp->cur+dtalen; }
if(newsiz>dbp->max) { errno=ETRUNC; return -1; }
if((newdta=realloc(dbp->dta,(vuns)newsiz))==NULL) { return -1; }
dbp->dta=newdta; dbp->siz=newsiz;
}
if(dtalen) {
if(xlt256) { dtb_xlt(((byte*)dbp->dta+dbp->cur),dtaptr,dtalen,xlt256); }
else { memcpy(((byte*)dbp->dta+dbp->cur),dtaptr,(vuns)dtalen); }
dbp->cur+=dtalen;
}
return 0;
}
static void dtb_xlt(void *dst,const void *src,vint len,const byte *tbl) {
byte *sp,*dp;
for(sp=(byte*)src,dp=(byte*)dst; len; len--,sp++,dp++) { *dp=tbl[*sp]; }
}
vint dtb_addtxt(DTABUF *dbp,const byte *xlt256,const byte *format,...) {
byte textÝ501¨;
va_list ap;
vint len;
va_start(ap,format); len=sprintf_len(format,ap)-1; va_end(ap);
if(len<0 || len>=sizeof(text)) { sprintf_safe(text,sizeof(text),"STRTOOLNG: %s",format); len=(int)strlen(text); }
else { va_start(ap,format); vsprintf(text,format,ap); va_end(ap); }
return dtb_adddta(dbp,xlt256,text,len);
}
vint dtb_rmvdta(DTABUF *dbp,vint len) {
if(!dbp) { errno=EINVAL; return -1; }
if(len > dbp->cur) { len=dbp->cur; }
dbp->cur-=len;
return 0;
}
vint dtb_reset(DTABUF *dbp) {
if(!dbp) { errno=EINVAL; return -1; }
dbp->cur=0;
if(dbp->siz > dbp->min) {
byte *newdta;
if((newdta=(byte*)realloc(dbp->dta,(vuns)dbp->min))==NULL) {
free(dbp->dta); dbp->dta=null; dbp->siz=0;
return -1;
}
dbp->dta=newdta; dbp->siz=dbp->min;
}
return 0;
}
void *dtb_elmptr(DTABUF *dbp,vint elmidx,vint elmlen) {
if(!elmlen || (elmidx*elmlen)>=dbp->cur) { return NULL; }
return ((byte*)dbp->dta+(elmidx*elmlen));
}
dtb.h
typedef _Packed struct {
vint min; /* initial size */
vint inc; /* increment size */
vint max; /* maximum size */
vint siz; /* current size */
vint cur; /* current data length */
void *dta; /* data pointer */
} DTABUF;
#define dtb_dtaptr(mDBP) (mDBP->dta)
#define dtb_dtalen(mDBP) (mDBP->cur)
DTABUF *dtb_crt(vint minsiz,vint incsiz,vint maxsiz);
DTABUF *dtb_dlt(DTABUF *dbp);
vint dtb_adddta(DTABUF *dbp,const byte *xlt256,const void *dtaptr,vint dtalen);
vint dtb_addtxt(DTABUF *dbp,const byte *xlt256,const byte *format,...);
vint dtb_rmvdta(DTABUF *dbp,vint len);
vint dtb_reset(DTABUF *dbp);
void *dtb_elmptr(DTABUF *dbp,vint elmidx,vint elmlen);
PS: vint sadece int bir typedef'ti - uzunluğunun platformdan platforma (taşıma için) değişken olduğunu hatırlatmak için kullandım.