CodeZine(コードジン)

特集ページ一覧

【第5回】委譲

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2008/12/25 11:00

目次

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);
}

  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

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

著者プロフィール

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

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

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5