hitode909の日記

以前はプログラミング日記でしたが、今は子育て日記です

Cでクラスを作ろうしたけどうまくいかなかった

Cでオブジェクト指向っぽくかわいい感じに書きたくて、試行錯誤してみたのだけど、うまくいかなかった。


要は、オブジェクトに変数と関数を入れてしましたい。最近オブジェクト指向脳なのでこう書けるとうれしい。
たとえばC++だとこう書けることを、Cでも似たように書きたい。

#include<iostream>
using namespace	std;

class Animal {
  string name;
public:
  Animal(string _name){
    name = _name;
  }
  void say(void){
    cout<<"Hello, I'm "<<name<<"."<<endl;
    return;
  }
};

int main(void){
  Animal a("neko");
  a.say();
  return 0;
}

aの変数を使う関数を呼ぶのを,a.say();で済ませられるのがかわいい。


これをふつうにCで書くとこうなる。

#include<stdio.h>

void say(char* s){
  printf("Hello, I'm %s.\n",s);
  return;
}

typedef struct {
  char name[16];
} animal;

int main(void){
  animal a = { "neko" };
  say(a.name);
  return 0;
}

say(a.name)をa.say();で呼べたらかわいいはず。


構造体に関数ポインタを入れて呼んでみる。

#include<stdio.h>

void say(char* s){
  printf("Hello, I'm %s.\n",s);
  return;
}

typedef struct {
  char name[16];
  void (*say)(char*);
} animal;

int main(void){
  animal a = { "neko", say };
  a.say(a.name);
  return 0;
}

a.say(a.name);と書くのはださいのでこれは微妙。オブジェクトと関数の対応はできているが,変数は対応できていない。
引数が必要ない関数の場合はa.say();と書けるが、これだと変数を扱えないのでやはりこれではだめ。


引数を構造体にすると引数のa.nameをaにできるが、関数側の汎用性がなくなってしまうし、やっぱりa.say(a);はおかしい。

#include<stdio.h>

typedef struct _animal{
  char name[16];
  void (*say)(struct _animal);
} animal;

void say(animal a){
  printf("Hello, I'm %s.\n",a.name);
  return;
}

int main(void){
  animal a = { "neko", say };
  a.say(a);
  return 0;
}


何の縛りもない場合はC++で書けばよいが,授業などでCで書くことが強制される場合にこのままでは苦痛を強いられることになるので,できればa.say();と書けるようにしたい。
今日はうまくいかなかったが、また思いついたら試すことにする。