オブジェクト指向の基本−クラス
クラス
リスト1では、オブジェクトの定義とその実体が1対1で紐づけられていました。しかし、この実装方法では、同じ属性と振る舞いを持つオブジェクトであっても個別に定義していかなければならず、大変に非効率です。その解決策としてクラスが登場します。
Wikipediaでは、クラスが次のように説明されています。
「オブジェクトの設計図にあたるもの。抽象データ型の一つ」(抜粋)
つまりクラスとは、オブジェクトの属性と振る舞いの定義を切り出して、それ自体に名前を付けたものです。リスト1で言うと、_object構造体にtypedefで名前付けを行うイメージです。これによって、同じ属性と振る舞いを持ったオブジェクトの生成を効率的かつ任意のタイミングで行えるようになります。また、クラスをもとにつくられたオブジェクトのことをインタンス(Instance)と呼びます(図3)。
なお、クラスの持つ「抽象データ型」という側面に関しては、次回以降詳細を説明するものとし、本稿では触れません。
では先ほどと同様に、クラスの概念をC言語を使って表現してみましょう。まずは、クラスの定義をObjectClass.hとして表現します(リスト2)。
#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)。
#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)。
#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言語を用いた実装例とともに解説しました。次回は今回解説した概念を発展させて、継承やカプセル化、ポリモーフィズムといったオブジェクト指向世界の特徴的な技術に触れたいと思います。
本稿が、少しでも皆さんのオブジェクト指向の理解に貢献できたのなら幸いです。次回もお楽しみに。

