SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Cでわかるオブジェクト指向

【第1回】オブジェクトとクラス


オブジェクト指向の基本−クラス

クラス

 リスト1では、オブジェクトの定義とその実体が1対1で紐づけられていました。しかし、この実装方法では、同じ属性と振る舞いを持つオブジェクトであっても個別に定義していかなければならず、大変に非効率です。その解決策としてクラスが登場します。

 Wikipediaでは、クラスが次のように説明されています。

 「オブジェクトの設計図にあたるもの。抽象データ型の一つ」(抜粋)

 クラス (コンピュータ) - Wikipedia

 つまりクラスとは、オブジェクトの属性と振る舞いの定義を切り出して、それ自体に名前を付けたものです。リスト1で言うと、_object構造体にtypedefで名前付けを行うイメージです。これによって、同じ属性と振る舞いを持ったオブジェクトの生成を効率的かつ任意のタイミングで行えるようになります。また、クラスをもとにつくられたオブジェクトのことをインタンス(Instance)と呼びます(図3)。

 なお、クラスの持つ「抽象データ型」という側面に関しては、次回以降詳細を説明するものとし、本稿では触れません。

図3:オブジェクトとクラスの関係
図3:オブジェクトとクラスの関係

 では先ほどと同様に、クラスの概念をC言語を使って表現してみましょう。まずは、クラスの定義をObjectClass.hとして表現します(リスト2)。

リスト2:C言語によるクラスの定義(ObjectClass.h)
#ifndef _OBJECTCLASS_H_INCLUDE_
#define _OBJECTCLASS_H_INCLUDE_

/* クラスの定義 */
typedef struct _object Instance;
struct _object{
  char *name;
  int status;
  int (*message)(Instance *self);
};

/* オブジェクト生成メソッド */
Instance *Object_new(char *name, int status);
/* オブジェクト破棄メソッド */
void Object_delete(Instance *obj);

#endif

 リスト2では、メソッドがオブジェクトの情報にアクセスできるように、引数でオブジェクトの実体(Instance *self)を渡しています。これは、メソッドとオブジェクトを関連付ける手段を言語的にサポートしていないC言語でOOPを実現する際の一般的な方法です。また、オブジェクトの生成および破棄を行うメソッドは、外部関数として定義しておきます。

 次に、クラスで定義された各メソッドをObjectClass.cとして実装します(リスト3)。

リスト3:クラスで定義された各メソッドを実装(ObjectClass.c)
#include "ObjectClass.h"
#include <stdio.h>
#include <stdlib.h>

/* メソッドの実装 */
static int Object_method(Instance *self)
{
  printf("%s.status = %d\n", self->name, self->status);
  return 1;
}

/* オブジェクト生成メソッド */
Instance *Object_new(char *name, int status)
{
  Instance *obj = (Instance *)malloc(sizeof(Instance));
  obj->name = name;
  obj->status = status;
  obj->message = Object_method;
  return obj;
}

/* オブジェクト破棄メソッド */
void Object_delete(Instance *obj)
{
  free(obj);
}

 最後に、main関数よりクラスを用いてオブジェクトの生成を行い、メッセージ送信を行う処理を実装します(リスト4)。

リスト4:オブジェクトを生成しメッセージ送信を行うmain関数(oop2.c)
#include "ObjectClass.h"

/* エントリポイント */
int main(int argc, char *argv[])
{
  /* オブジェクトの生成 */
  Instance *obj1 = Object_new("obj1", 50);
  Instance *obj2 = Object_new("obj2", 100);

  /* オブジェクトにメッセージを送信 */
  obj1->message(obj1);
  obj2->message(obj2);

  /* オブジェクトの破棄 */
  Object_delete(obj1);
  Object_delete(obj2);

  return 1;
}

 これらのコードを実行した結果は、次のようになります。

>gcc oop2.c ObjectClass.c
>./a.out
obj1.status = 50
obj2.status = 100

 クラスを定義したことによって、同じ構成情報を持つ2つのオブジェクトを効率的に生成できました。併せて、それぞれのオブジェクトがきちんと固有の振る舞いをすることも確認されました。

まとめ

 いかがだったでしょうか。今回はOOPの基本であるオブジェクトとメッセージ、それらを効率的に管理するクラスといった概念を、C言語を用いた実装例とともに解説しました。次回は今回解説した概念を発展させて、継承やカプセル化、ポリモーフィズムといったオブジェクト指向世界の特徴的な技術に触れたいと思います。

 本稿が、少しでも皆さんのオブジェクト指向の理解に貢献できたのなら幸いです。次回もお楽しみに。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
Cでわかるオブジェクト指向連載記事一覧

もっと読む

この記事の著者

島田 浩二(Ruby札幌)(シマダ コウジ)

1978年生まれ。電気通信大学電気通信学部情報工学科卒業後、メーカ系ソフトウェア会社にて携帯電話の開発業務に従事した後、2006年より札幌にてフリーのプログラマとして活動。2009年7月に株式会社えにしテックを設立し、同社代表取締役に就任。 日本Rubyの会理事、一般社団法人LOCAL理事、Ruby札幌主宰。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/3706 2009/03/17 12:59

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー