北海道苫小牧市出身の初老PGが書くブログ

永遠のプログラマを夢見る、苫小牧市出身のおじさんのちらしの裏

無理矢理ポリモフィズム

C言語ポリモルフィズムしてみた。参考にさせて頂いたのはこちら



#include <stdio.h>

/*
動物クラス多態スキーマ =====================================================
*/

// クラスが持つ関数の実装を保存する
typedef struct {
void (*hello)();
int size;
} Animal_Sc;

/*
動物クラス多態インタフェース ===============================================
*/

//それぞれのオブジェクトに多態性を組み合わせる
typedef struct {
Animal_Sc* sc; // ←グローバルで一つだけ各クラスに存在している
void* obj;
} Animal_Inf;

//多体制を持った関数
void Animal_Inf_hello( Animal_Inf this )
{
if ( this.sc->hello == NULL ) perror("no hello method");
this.sc->hello( this.obj );
}

/*
動物参照クラス =============================================================
*/

//この例ではなくてもいいかも?
typedef struct {
Animal_Inf super;
} Animal_Refer;

void Animal_Refer_init( Animal_Refer* animal, Animal_Inf super ){
animal->super = super;
}

void Animal_Refer_hello(Animal_Refer* this )
{
Animal_Inf_hello( this->super );
}


/*
犬クラス ===================================================================
*/

Animal_Sc Dog_sc;

typedef struct {
} Dog;

void Dog_hello() {
printf("bow wow\n");
}

Animal_Inf Dog_inf_Animal( Dog* this )
{
static int initialized = 0;
Animal_Inf inf;

if ( ! initialized ) {
Dog_sc.hello = Dog_hello;
Dog_sc.size = sizeof(Dog);
initialized = 1;
};

inf.sc = &Dog_sc;
inf.obj = this;

return inf;
}


/*
猫クラス ===================================================================
*/

Animal_Sc Cat_sc;

typedef struct {
} Cat;

void Cat_hello() {
printf("miaow...\n");
}

Animal_Inf Cat_inf_Animal( Cat* this )
{
static int initialized = 0;
Animal_Inf inf;

if ( ! initialized ) {
Cat_sc.hello = Cat_hello;
Cat_sc.size = sizeof(Cat);
initialized = 1;
};

inf.sc = &Cat_sc;
inf.obj = this;

return inf;
}

/*
メインルーチン =============================================================
*/

int main(char *argv[], int argc){
Animal_Refer animal[4]; //動物配列
Dog dog1; //サブクラスの初期化は省略
Dog dog2;
Cat cat1;
Cat cat2;
int i;
Animal_Inf super; //汎用。インタフェースを保存

//多態性を持ったインスタンスの生成
super = Dog_inf_Animal(&dog1);
Animal_Refer_init(&animal[0], super);
super = Cat_inf_Animal(&cat1);
Animal_Refer_init(&animal[1], super);
super = Cat_inf_Animal(&cat2);
Animal_Refer_init(&animal[2], super);
super = Dog_inf_Animal(&dog2);
Animal_Refer_init(&animal[3], super);

//多態性メソッドを実行
for(i = 0; i < 4; i++){
Animal_Refer_hello(&animal[i]);
}
return 0;
}

/*
[結果]
bow wow
miaow...
miaow...
bow wow
*/





め、めんどくさー。高級言語のありがたみがよくわかる結果になったなあ。