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

今回は、このメンバに対して、以下の機能拡張を考えます。
- メンバはサービスステータス(例:ゴールド、シルバー、ブロンズ)を持つ
- サービスステータスは変更することが可能
これを継承の仕組みで実現すると、以下のようなモデルになります。

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

まずは、サービスステータスを以下のようにクラス定義します。
#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
次に、内部の構造は以下のようになります。
/* 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);
最後に、メソッドの実装を行います。
#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);
}
