C言語による多態化
2914 ワード
総括する
マルチステート性はオブジェクト向けプログラム設計の重要な特徴であり,マルチステート性を利用して拡張しやすいシステムを設計し実現することができる.
その名の通り、多態の意味は多種の形態で、C++プログラム設計の中で、多態は:異なる機能を持つ関数は同じ関数名を使うことができて、このように1つの関数名で異なる内容の関数を呼び出すことができます.
C++の多態は静的多態性と動的多態性の2種類に分けられる.
1.C++の関数リロードと演算子リロードで実現される多態性は静的多態性に属し、プログラムコンパイル時にシステムが呼び出す関数を決定できるため、静的多態性はコンパイル時多態性とも呼ばれる.静的多態性は関数リロードによって実現される(演算子リロードは実質的に関数リロードでもある).
2.動的マルチステートプログラムの実行中に、操作ポインタが指すオブジェクトを動的に決定します.ランタイムマルチステートとも呼ばれます.動的多態は虚関数によって実現される.
C言語はオブジェクト向けの言語ではないが,C言語は同様に多態性を実現することができ,LinuxカーネルにはC言語を利用して多態性を実現するコードが大量に存在する.
C言語によるコンパイル時の多態性の実現
C言語はマクロによってコンパイル時のマルチステートを実現することができ、以下の例である.
異なるタイプのAおよびBの場合、パラメータ付きマクロADDは、intタイプまたはstringタイプが入力されることに応じて異なる+のポリシーをとる.
C言語による動的多態性の実現
C言語では、関数ポインタを使用してダイナミックマルチステートを実装できます.次の例を示します.
上のコードは多態の性質を実現しただけでなく,実際にはC++におけるクラスの継承をシミュレートしている.メイン関数ではベースクラスポインタbasが最初にベースクラスオブジェクトを指すため、呼び出しdanceとjumpはベースクラスのdance jumpである.次にbasを派生クラスのオブジェクトに向ける、danceとjumpを呼び出すときはベースクラスのdanceとjumpではなく、派生クラスのdanceとjumpに変換する.
マルチステート性はオブジェクト向けプログラム設計の重要な特徴であり,マルチステート性を利用して拡張しやすいシステムを設計し実現することができる.
その名の通り、多態の意味は多種の形態で、C++プログラム設計の中で、多態は:異なる機能を持つ関数は同じ関数名を使うことができて、このように1つの関数名で異なる内容の関数を呼び出すことができます.
C++の多態は静的多態性と動的多態性の2種類に分けられる.
1.C++の関数リロードと演算子リロードで実現される多態性は静的多態性に属し、プログラムコンパイル時にシステムが呼び出す関数を決定できるため、静的多態性はコンパイル時多態性とも呼ばれる.静的多態性は関数リロードによって実現される(演算子リロードは実質的に関数リロードでもある).
2.動的マルチステートプログラムの実行中に、操作ポインタが指すオブジェクトを動的に決定します.ランタイムマルチステートとも呼ばれます.動的多態は虚関数によって実現される.
C言語はオブジェクト向けの言語ではないが,C言語は同様に多態性を実現することができ,LinuxカーネルにはC言語を利用して多態性を実現するコードが大量に存在する.
C言語によるコンパイル時の多態性の実現
C言語はマクロによってコンパイル時のマルチステートを実現することができ、以下の例である.
#define ADD(A, B) (A) + (B);
int main(){
int a =1;
int b =2;
cout<
異なるタイプのAおよびBの場合、パラメータ付きマクロADDは、intタイプまたはstringタイプが入力されることに応じて異なる+のポリシーをとる.
C言語による動的多態性の実現
C言語では、関数ポインタを使用してダイナミックマルチステートを実装できます.次の例を示します.
#include
#include
//
struct base_vtbl
{
void(*dance)(void *);
void(*jump)(void *);
};
//
struct base
{
/*virtual table*/
struct base_vtbl *vptr;
};
void base_dance(void *this)
{
printf("base dance
");
}
void base_jump(void *this)
{
printf("base jump
");
}
/* global vtable for base */
struct base_vtbl base_table =
{
base_dance,
base_jump
};
//
struct base * new_base()
{
struct base *temp = (struct base *)malloc(sizeof(struct base));
temp->vptr = &base_table;
return temp;
}
//
struct derived1
{
struct base super;
/*derived members */
int high;
};
void derived1_dance(void * this)
{
/*implementation of derived1's dance function */
printf("derived1 dance
");
}
void derived1_jump(void * this)
{
/*implementation of derived1's jump function */
struct derived1* temp = (struct derived1 *)this;
printf("derived1 jump:%d
", temp->high);
}
/*global vtable for derived1 */
struct base_vtbl derived1_table =
{
(void(*)(void *))&derived1_dance,
(void(*)(void *))&derived1_jump
};
//
struct derived1 * new_derived1(int h)
{
struct derived1 * temp= (struct derived1 *)malloc(sizeof(struct derived1));
temp->super.vptr = &derived1_table;
temp->high = h;
return temp;
}
int main(void)
{
struct base * bas = new_base();
//
bas->vptr->dance((void *)bas);
bas->vptr->jump((void *)bas);
struct derived1 * child = new_derived1(100);
//
bas = (struct base *)child;
//
bas->vptr->dance((void *)bas);
bas->vptr->jump((void *)bas);
return 0;
}
上のコードは多態の性質を実現しただけでなく,実際にはC++におけるクラスの継承をシミュレートしている.メイン関数ではベースクラスポインタbasが最初にベースクラスオブジェクトを指すため、呼び出しdanceとjumpはベースクラスのdance jumpである.次にbasを派生クラスのオブジェクトに向ける、danceとjumpを呼び出すときはベースクラスのdanceとjumpではなく、派生クラスのdanceとjumpに変換する.