2009年6月14日日曜日

C 言語の話#3 オブジェクト指向プログラミング?

オブジェクト指向プログラミング?を C言語でやってみた.オブジェクト指向プログラミングというよりも,カプセル化をやっているだけなのだけどねw

論じるよりソースを見てもらえると早い.やってみたのはこんなかんじのことだ.
/* main.c */
#include <stdio.h>
#include "book.h"

int main(void)
{
Book *book;

book = newBook("伝奇集", "J.L. ボルヘス");

printf("%s\t%s\n", book->getTitle(book), book->getAuthor(book));

deleteBook(book);

return 0;
}

new でつくって,アクセッサで値を参照して,delete で解放する.基本的なルールはこんなかんじ.

・「クラス名 *インスタンス変数名;」でインスタンス変数を宣言する.
・「インスタンス変数 = newクラス名(引数…);」でインスタンス化する.
・「インスタンス変数名->関数名(インスタンス変数名, 引数…)」で関数を呼び出す.
・「deleteクラス名(インスタンス変数名);」でインスタンスを解放する.

new と delete の対応に気をつけさえすれば,Book クラスのメモリのことを気にしなくていいようになっている.(理想としてはね.)

book.h と book.c の実装はこんな感じ.
/* book.h */
#ifndef __BOOK_H__
#define __BOOK_H__

typedef struct _Book Book;

struct _Book {
char *title;
char *author;
char *((*getTitle)(const Book *book));
char *((*getAuthor)(const Book *book));
};

Book *newBook(const char *title, const char *author);
void deleteBook(Book *book);

#endif /* __BOOK_H__ */
/* book.c */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "book.h"

char *book_getTitle(const Book *book);
char *book_getAuthor(const Book *book);

Book *newBook(const char *title, const char *author)
{
Book *book;

book = (Book *)malloc(sizeof(Book));
if (book == NULL) {
fprintf(stderr, "%s:%d: error: %s()\n", __FILE__, __LINE__, __func__);
return NULL;
}

book->title = (char *)malloc(strlen(title) + 1);
if (book->title == NULL) {
free(book);
fprintf(stderr, "%s:%d: error: %s()\n", __FILE__, __LINE__, __func__);
return NULL;
}
book->author = (char *)malloc(strlen(author) + 1);
if (book->author == NULL) {
free(book->title);
free(book);
fprintf(stderr, "%s:%d: error: %s()\n", __FILE__, __LINE__, __func__);
return NULL;
}

strcpy(book->title, title);
strcpy(book->author, author);

book->getTitle = book_getTitle;
book->getAuthor = book_getAuthor;

return book;
}

void deleteBook(Book *book)
{
free(book->author);
free(book->title);

free(book);
}

char *book_getTitle(const Book *book)
{
return book->title;
}

char *book_getAuthor(const Book *book)
{
return book->author;
}

こういう実装が好きでよくやるのだけど,もっといい方法があったら教えてほしい.

0 件のコメント: