構造体内で関数ポインターを使用することは、構造体内に関数をカプセル化することと関係があると思います...?もしそうなら、これはどのくらい正確に達成されますか?
そして、単に関数を定義するのではなく、構造体の中に関数ポインタを置くことは、どのような利点をもたらしますか?
構造体内で関数ポインターを使用することは、構造体内に関数をカプセル化することと関係があると思います...?もしそうなら、これはどのくらい正確に達成されますか?
そして、単に関数を定義するのではなく、構造体の中に関数ポインタを置くことは、どのような利点をもたらしますか?
構造内の関数ポインタは、Cでのオブジェクトプログラミングのベースです(http://www.planetpdf.com/codecuts/pdfs/ooc.pdfを参照)。それは本当に中規模から大規模のCプロジェクトに適しています。
例:
ヘッダ:
typedef struct TPile
{
int(*Push)(struct TPile*, int);
int(*Pop)(struct TPile*);
void(*Clear)(struct TPile*);
void(*Free)(struct TPile*);
int(*Length)(struct TPile*);
void(*View)(struct TPile*);
int Nombre;
struct Titem *Top;
} TPile ;
ソース:
TPile TPile_Create()
{
TPile This;
TPile_Init(&This);
This.Free = TPile_Free;
return This;
}
TPile* New_TPile()
{
TPile *This = malloc(sizeof(TPile));
if(!This) return NULL;
TPile_Init(This);
This->Free = TPile_New_Free;
return This;
}
void TPile_Clear(TPile *This)
{
Titem *tmp;
while(This->Top)
{
tmp = This->Top->prec;
free(This->Top);
This->Top = tmp;
}
This->Nombre = 0;
}
構造体内に関数ポインタがあると、バイナリ検索ツリーなどの特定のデータ構造に役立ちます。
たとえば、構造体がである要素を挿入したい
struct Employee {
int eid;
char *name;
};
二分探索木に。しかし、BSTで関数を使用して、保存および検索中に要素を比較したいと思います。
bst構造体は次のようになります。
struct BST {
struct _node *root;
int (*compare)(void *e1 , void *e2);
};
ここで、BSTを次のように使用します。
int main(void){
struct Emp e1 = { 1, "John" };
struct BST *t = create_tree();
t->set_compare( &compare );
t->insert(e1);
t->get(e1);
...
}
int compare(void *e1 , void *e2)
{
//type cast e1, e2 as struct Emp
// return the comparison result based on id
}
私が見る利点は、この関数ポインターをすべてのBST操作関数に渡し続ける必要がないことです。
しかし、すべてのパブリック関数をstruct内に格納すると、他の人が言うように、Cコード内にOOPスタイルがもたらされます。
関数が2つの変数を取り、4つの異なる関数を呼び出すと仮定します。次のような構造があるとします。
/* Input 1 Input 2 Function pointer
{
{ 0, 0, Function00},
{ 0, 1, Function01},
{ 1, 0, Function10},
{ 1, 1, Function11}
}
入力値を構造体の値と比較し、対応する関数を呼び出すのは簡単です。
if..else ...を使用する方が良いように思われるかもしれませんが、そのようなケースが100を超える場合を考えてみてください。
構造体に関数ポインタを定義することの利点は、コード設計に関連しています。目標は、コードをより構造化することです。
構造体で変数と関数を定義することは、指向オブジェクト言語でクラスを定義することに似ています
詳細については、次のリンクを参照してください