C言語でオブジェクト指向ってこうゆうこと?
なんか世の中には、C言語でオブジェクト指向的な書き方を説明した本が有るとのこと。
ん〜、こんな感じかな?c11のthreads.hを試したメモ - 会者定離で以降のときに作った残念Stackを、オブジェクト指向っぽく書き直したの。
ちなみにStackサイズ固定なのは、可変実装がむずかしそうだったのと固定でないとFullにならないから*1><
enum{S_SIZE = 10}; typedef struct Stack{ int v_[S_SIZE]; /* int vsize_; */ int vused_; mtx_t mtx_; cnd_t cnd_push_; cnd_t cnd_pop_; } Stack10; int stack10_Constructor(Stack10 *s){ int ret; ret = mtx_init(&s->mtx_, mtx_plain); if(ret != thrd_success){ return ret; } ret = cnd_init(&s->cnd_push_); if(ret != thrd_success){ return ret; } ret = cnd_init(&s->cnd_pop_); if(ret != thrd_success){ return ret; } return 0; } void stack10_Destructor(Stack10 *s){ mtx_destroy(&s->mtx_); cnd_destroy(&s->cnd_push_); cnd_destroy(&s->cnd_pop_); } int stack10_push(Stack10 *s, int x){ mtx_lock(&s->mtx_); while(s->vused_ >= S_SIZE){ cnd_wait(&s->cnd_push_, &s->mtx_); } s->v_[s->vused_++] = x; cnd_signal(&s->cnd_pop_); mtx_unlock(&s->mtx_); return 0; } int stack10_pop(Stack10 *s, int *x){ mtx_lock(&s->mtx_); while(s->vused_ == 0){ cnd_wait(&s->cnd_pop_, &s->mtx_); } *x = s->v_[--s->vused_]; cnd_signal(&s->cnd_push_); mtx_unlock(&s->mtx_); return 0; }
使うときは、こんな感じ。個人的にmalloc/freeしなくて済むならそっちのほうが好きなので、「stack10_Constructor()で、Stack10構造体をmallocして〜」って実装にはしなかった。
ほい、まあC言語っぽくてやっつけにしては良さげである^^
まあ素直に、C++使っとけって感じである。
int func(void *arg) { int i; Stack10 *s =(Stack10*)arg; printf("thrd_current()vim is %ld\n", (unsigned long int)thrd_current()); for(i = 0; i<3; ++i){ stack10_push(s, i); } return 0; } int main() { int i, n; Stack10 s = {{0},0}; enum {SIZE = 4}; thrd_t thr_s[SIZE]; /* * init */ stack10_Constructor(&s); /* * run */ for(i=0; i<SIZE; i++) { thrd_create(&thr_s[i], func, (void*)(Stack10*)&s); } for(i=0; i<(SIZE*3); i++){ stack10_pop(&s, &n); printf("%d : %d\n",i,n); } for(i=0; i<SIZE; i++) { thrd_join(thr_s[i], 0); } /* * destroy */ stack10_Destructor(&s); return 0; }
P.S. 2015Apr25
なんの本で読んで知ったか思い出した。
読書会で読んだC++のためのAPIデザインの「5.1.3. ANSI CによるAPIの記述」で、こんなStackのC言語オブジェクト指向でのAPI設計を読んだ読んだ><
まあ結構スタンダードな実装方法だとは思うので、コメントで教えて貰ったように、なんかのドライバでも似たような実装を見たもする。
C++のためのAPIデザインposted with amazlet at 15.04.24
*1:threadのwaitさせたかったので、固定長でpop待ちさせるためです