2012-01-19 15 views
2

Cでオブジェクトメソッドをエミュレートすることはできますか?私は、実際にsave_foo(bar)を呼び出し、bar->save()メンバ関数の引数例えば:Cでオブジェクトメソッドをエミュレートすることは可能ですか?

struct foo { 
    int a; 
    int (*save)(struct foo *); 
}; 

int 
save_foo(struct foo *bar) { 
    // do stuff. 
} 

struct foo * 
create_foo() { 
    struct foo *bar = malloc(sizeof(struct foo)); 
    bar->save = save_foo; 

    return bar; 
} 

int 
main() { 
    struct foo *bar = create_foo(); 

    bar->a = 10; 
    bar->save(); 
} 

にパラメータとして可能な自己参照に構造を可能にしたいと思います。長いショットのようですが、かなり滑らかです:)

+1

他のすべての言語がオブジェクトメソッドをエミュレートし、そのほとんどがC言語で少なくとも部分的に実装されているため、this(別名bar)を自動的に渡すことはできません。 .planetpdf.com/codecuts/pdfs/ooc.pdf) –

+3

C++が必要な場合は、単にC++コンパイラを使用するだけではいかがですか? –

+1

@BoPersson - 彼が実装しようとしているオブジェクト指向はC++のオブジェクトモデルではないので? –

答えて

4

いいえ、これはできません。そこCでオブジェクト指向のライブラリがありますが、それらは明示的にこのスタイルの例についてはBerkeley DB CのAPIを参照してください

bar->save(bar); 

のような「方法」に「this」オブジェクトを渡しますが、Cの使用を検討してください++ OOをCのような言語でしたい場合はObjective-Cを使用します。

+0

あなたは 'int save(struct foo * obj){obj-> save(obj); '' save(bar) 'の呼び出しを簡略化します - 正しい順序ではなく、十分に近く、繰り返しはありません。 –

+0

@ChrisLutz:繰り返しはまだ残っていますが、今は 'save'関数でラップされています(他のすべての"メソッド "の場合はフリースタンディングラッパー)。 –

+0

'#define M(オブジェクト、メソッド、...)((オブジェクト) - >メソッド(オブジェクト、__VA_ARGS __))'はどうですか? –

2

基本的に、 Cの関数への参照は、ポインタが置かれている場所へのポインタです。ポインタを呼び出すときには、ポインタを構造体から取り出し、そこにジャンプしてコンテキストやスタックに関する知識がなくても実行を続けるだけです。どこからでも "これ"を取ることはできません。

1

答えは「はい」です。

最初のC++コンパイラはコンパイラではありませんでした。彼らは単にC++コードをCコードに翻訳しました。 CFrontコンパイラがこれを行いました。

他の回答から、おそらくあなたの質問が間違っていることが分かります。いいえ、あなたが書いた文法はC言語ではうまくいきません。自分のタイプのプリプロセッサ/トランスレータを書いて、bar->save()からfoo_save(bar)、さらにはC3fooF4save(bar)に変換する必要があります。

+0

質問はOOPパラダイムを使用することではありません(どんな言語でもできますが、そうすべきではありません)。質問は、私の知る限り、カスタム(そして非常に賢い)プリプロセッサなしでは不可能な、特定の構文構造に関するものです。同様に、CFront。 –

1

はい、save関数ポインタにbarを渡し、そしてあなたはC++がボンネット下何があるでしょう(目に見えないメソッドへの最初のパラメータとしてthisを渡します)。

+0

これはObjective-Cがフードの中で行うことに近いです。メソッドルックアップは実行時に関数ポインタによって解決されますが、C++ではコンパイル時に解決されます。つまり、C++コードは 'save_foo(bar)関数ポインタ間接はありません。 –

+0

C++仮想関数。 –

関連する問題