C言語でオブジェクト指向に挑戦してみる
「オブジェクト指向でなぜつくるのか」という本を買って、ちょっとずつ読んでいます。
オブジェクト指向でなぜつくるのか―知っておきたいプログラミング、UML、設計の基礎知識―
- 作者: 平澤章
- 出版社/メーカー: 日経BP社
- 発売日: 2004/06/03
- メディア: 単行本
- 購入: 34人 クリック: 448回
- この商品を含むブログ (198件) を見る
なので、C言語でなんとかオブジェクト指向の真似事をしてみようという試みです。上手くいけば仕事にも活かせるかもしれません。
検索してみると、以下のようなサイトが出てくるので読んで色々テクを身につけたいと思います。
ただ、それだけでこのエントリを終わらせるのもアレなので、とりあえず自分が今できる範囲でオブジェクト指向っぽい書き方がどの程度できるのか、試してみました。
コードは最後に添付するとして、現状できたコードを見ての感想は以下のとおり。
- ##演算子を使うと、なんかそれっぽくできる。(参考:#と##演算子)
- 無駄に構造体本体や型名を引数にとっていてかっこ悪い
- クラスメソッドはもっと上手く書けるんじゃないだろうか。関数ポインタの使い方がミソ?
- コンストラクタはもっときれいに書きたい
というわけで、張り切って勉強するのです。
今回できたコード
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct _human_ { char *(*getName)(struct _human_ *h); int (*getAge)(struct _human_ *h); void (*destructor)(struct _human_ *h); char* name; int age; } Human; #define new(klass, ...) klass##_new(__VA_ARGS__) #define delete(obj) (obj)->destructor((obj)) #define setfunc(klass, func) klass##_##func char* Human_getName(Human *thiz) { return thiz->name; } int Human_getAge(Human *thiz) { return thiz->age; } void Human_delete(Human *h) { free(h->name); free(h); printf("human deleted\n"); return; } Human* Human_new(char *name, int age) { Human *h; h = (Human*)malloc(sizeof(Human)); h->getAge = setfunc(Human, getAge); h->getName = setfunc(Human, getName); h->destructor = setfunc(Human, delete); h->name = strdup(name); h->age = age; printf("human initialized\n"); return h; } int main(int argc, char *argv[]) { Human *suzuki; suzuki = new(Human, "suzuki", 20); printf("%s's age: %d\n", suzuki->getName(suzuki), suzuki->getAge(suzuki)); delete(suzuki); return 0; }
追記
- deleteの引数に、クラス名を使わずに済むようデストラクタを定義