SHOEISHA iD

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

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

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

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

【第5回】委譲


Cによる委譲の実現(1)

 前回実装したメンバとゲストのサンプルをベースに、委譲を使って機能を拡張してみたいと思います。

図4:前回作成したモデル
図4:前回作成したモデル

 今回は、このメンバに対して、以下の機能拡張を考えます。

  • メンバはサービスステータス(例:ゴールド、シルバー、ブロンズ)を持つ
  • サービスステータスは変更することが可能

 これを継承の仕組みで実現すると、以下のようなモデルになります。

図5:継承による実現
図5:継承による実現

 これを、今回は以下のように委譲を使って実現してみたいと思います。

図6:今回作成するモデル
図6:今回作成するモデル

 まずは、サービスステータスを以下のようにクラス定義します。

リスト1:ServiceStatus.h
#ifndef _SERVICESTATUS_H_INCLUDE_
#define _SERVICESTATUS_H_INCLUDE_

/* ServiceStatusクラス定義 */
typedef struct _service_status ServiceStatus;
struct _service_status{
    void* service_status_private_data;
    int (*changeServiceStautsTo)(ServiceStatus *self, char* new_staus);
};

/* オブジェクト生成メソッド */
ServiceStatus *ServiceStatus_new(char *status);

/* オブジェクト破棄メソッド */
void ServiceStatus_delete(ServiceStatus *obj);

#endif

 次に、内部の構造は以下のようになります。

リスト2:ServiceStatus.private.h
/* ServiceStatus属性定義 */
struct _service_status_attribute {
    char* status;
};

/* ServiceStatus属性アクセス用マクロ */
#define SERVICESTATUS_ATTRIBUTE(ptr) ¥
    ((struct _service_status_attribute*)(ptr->service_status_private_data))

/* 初期化・終了処理 */
ServiceStatus* ServiceStatus_initialize(ServiceStatus* self, char* status);
void ServiceStatus_finalize(ServiceStatus* self);

 最後に、メソッドの実装を行います。

リスト3:ServiceStatus.c
#include "ServiceStatus.h"
#include "ServiceStatus.private.h"

#include <stdlib.h>
#include <stdio.h>

/* サービスステータス変更 */
static int ServiceStatus_changeServiceStautsTo(ServiceStatus *self, char* new_staus)
{
    SERVICESTATUS_ATTRIBUTE(self)->status = new_status;
    printf("現在のサービスステータスは %s です¥n", SERVICESTATUS_ATTRIBUTE(self)->status);
    return 1;
}

/* オブジェクト初期化メソッド */
ServiceStatus* ServiceStatus_initialize(ServiceStatus* self, char* status)
{
    self->service_status_private_data = malloc(sizeof(struct _service_status_attribute));
    SERVICESTATUS_ATTRIBUTE(self)->status = staus;
    printf("現在のサービスステータスは %s です¥n", SERVICESTATUS_ATTRIBUTE(self)->status);
    self->changeServiceStautsTo = ServiceStatus_changeServiceStautsTo;
    return self;
}

/* オブジェクト終了処理メソッド */
void ServiceStatus_finalize(ServiceStatus* self)
{
    free(SERVICESTATUS_ATTRIBUTE(self));
}

/* オブジェクト生成メソッド */
ServiceStatus* ServiceStatus_new(char* status)
{
    ServiceStatus* obj = (ServiceStatus*)malloc(sizeof(ServiceStatus));
    return ServiceStatus_initialize(obj, status);
}

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

次のページ
Cによる委譲の実現(2)

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

Cでわかるオブジェクト指向連載記事一覧

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/3710 2009/03/17 13:14

イベント

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

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

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

メールバックナンバー