オブジェクト指向のようなコードをC
プログラミング言語で書く方法はありますか?
以下も参照してください。
「[c]oo」で検索すると出てきます。
オブジェクト指向のようなコードをC
プログラミング言語で書く方法はありますか?
以下も参照してください。
「[c]oo」で検索すると出てきます。
C++ は C からそれほど離れていません。
クラスは、VTable と呼ばれる関数ポインターのテーブルへの隠しポインターを持つ構造体です。Vtable 自体は静的です。型が同じ構造の Vtable を指しているが、ポインターが他の実装を指している場合、ポリモーフィズムが発生します。
コードの混乱を避けるために、構造体をパラメーターとして受け取る関数の呼び出しロジックをカプセル化することをお勧めします。
また、構造体のインスタンス化と初期化を関数 (これは C++ コンストラクターに相当) と削除 (C++ のデストラクタ) にカプセル化する必要があります。とにかく、これらは良い習慣です。
typedef struct
{
int (*SomeFunction)(TheClass* this, int i);
void (*OtherFunction)(TheClass* this, char* c);
} VTable;
typedef struct
{
VTable* pVTable;
int member;
} TheClass;
メソッドを呼び出すには:
int CallSomeFunction(TheClass* this, int i)
{
(this->pVTable->SomeFunction)(this, i);
}
私は他のみんなの答えを見て、これを思いつきました:
#include <stdio.h>
typedef struct
{
int (*get)(void* this);
void (*set)(void* this, int i);
int member;
} TheClass;
int Get(void* this)
{
TheClass* This = (TheClass*)this;
return This->member;
}
void Set(void* this, int i)
{
TheClass* This = (TheClass*)this;
This->member = i;
}
void init(TheClass* this)
{
this->get = &Get;
this->set = &Set;
}
int main(int argc, char **argv)
{
TheClass name;
init(&name);
(name.set)(&name, 10);
printf("%d\n", (name.get)(&name));
return 0;
}
それがいくつかの質問に答えることを願っています。
VPRI の Ian Piumartaと Alessandro Warth による記事Open Reusable Object Modelsの付録 B は、約 140 行のコードからなる GNU C でのオブジェクト モデルの実装です。それは魅力的な読み物です!
以下は、C への GNU 拡張機能 (ステートメント式)を使用して、オブジェクトにメッセージを送信するマクロのキャッシュされていないバージョンです。
struct object;
typedef struct object *oop;
typedef oop *(*method_t)(oop receiver, ...);
//...
#define send(RCV, MSG, ARGS...) ({ \
oop r = (oop)(RCV); \
method_t method = _bind(r, (MSG)); \
method(r, ##ARGS); \
})
同じドキュメントで、、、および構造体、object
および関数を見てください。vtable
vtable_delegated
symbol
_bind
vtable_lookup
乾杯!
#include <stdio.h>
typedef struct {
int x;
int z;
} base;
typedef struct {
base;
int y;
int x;
} derived;
void function_on_base( base * a) // here I can pass both pointers to derived and to base
{
printf("Class base [%d]\n",a->x);
printf("Class base [%d]\n",a->z);
}
void function_on_derived( derived * b) // here I must pass a pointer to the derived class
{
printf("Class derived [%d]\n",b->y);
printf("Class derived [%d]\n",b->x);
}
int main()
{
derived d;
base b;
printf("Teste de poliformismo\n");
b.x = 2;
d.y = 1;
b.z = 3;
d.x = 4;
function_on_base(&b);
function_on_base(&d);
function_on_derived(&b);
function_on_derived(&d);
return 0;
}
出力は次のとおりです。
Class base [3]
Class base [1]
Class base [4]
Class derived [2]
Class derived [3]
Class derived [1]
Class derived [4]
動作するので、多態的なコードです。
UncleZeiv は最初にそれについて説明しました。
ウィキペディアから: プログラミング言語と型理論では、ポリモーフィズム (ギリシャ語の πολύς、polys、「多くの、多くの」および μορφή、morphē、「フォーム、シェイプ」に由来) は、さまざまなタイプのエンティティへの単一のインターフェイスを提供することです。
したがって、C で実装する唯一の方法は、(半) 自動型情報管理と共に可変引数を使用することです。たとえば、C++ では次のように記述できます (些細なことで申し訳ありません)。
void add( int& result, int a1, int a2 );
void add( float& result, float a1, float a2 );
void add( double& result, double a1, double a2 );
C では、他のソリューションの中でも特に、次のようなことができます。
int int_add( int a1, int a2 );
float float_add( float a1, fload a2 );
double double_add( double a1, double a2 );
void add( int typeinfo, void* result, ... );
次に、次のものが必要です。
ポリモーフィズムの他の実装は、まさにこの実装によく似ているはずです。代わりに、上記の回答は、ポリモーフィズムよりも継承に対処しようとしているようです!