6

データの抽象化について私が理解したのは、技術的な詳細をユーザーから隠し、必要な詳細のみを表示することです。したがって、データの抽象化は OOP 機能です。私の質問は: C はデータの抽象化もサポートしていますか?

もしそうなら、なぜデータ抽象化はオブジェクト指向プログラミング言語の機能であり、手続き型言語の機能ではないのですか?

私の質問に対する答えが「いいえ」の場合、C の構造体や列挙型はどうでしょうか。また、ユーザーから詳細を隠します。

4

2 に答える 2

5

C でオブジェクト指向プログラミングを行うことは確かに可能です。たとえば、最初の C++ コンパイラは実際には C++ から C へのトランスパイラであり、Python VM は C で書かれていることなどを思い出してください。いわゆる OOP 言語を他の言語と区別するものは、これらの構造、たとえば構文。

抽象化を提供する一般的な方法の 1 つは、関数ポインターです。以下の Linux カーネル ソースの構造体を見てください (include/linux/virtio.h から)。

/**
 * virtio_driver - operations for a virtio I/O driver
 * @driver: underlying device driver (populate name and owner).
 * @id_table: the ids serviced by this driver.
 * @feature_table: an array of feature numbers supported by this driver.
 * @feature_table_size: number of entries in the feature table array.
 * @probe: the function to call when a device is found.  Returns 0 or -errno.
 * @remove: the function to call when a device is removed.
 * @config_changed: optional function to call when the device configuration
 *    changes; may be called in interrupt context.
 */
struct virtio_driver {
        struct device_driver driver;
        const struct virtio_device_id *id_table;
        const unsigned int *feature_table;
        unsigned int feature_table_size;
        int (*probe)(struct virtio_device *dev);
        void (*scan)(struct virtio_device *dev);
        void (*remove)(struct virtio_device *dev);
        void (*config_changed)(struct virtio_device *dev);
#ifdef CONFIG_PM
        int (*freeze)(struct virtio_device *dev);
        int (*restore)(struct virtio_device *dev);
#endif
};

probe、などはすべてscanremoveI/O ドライバーが自身で設定する関数ポインターです。その後、カーネルは、デバイスについて何も知らなくても、任意の I/O ドライバーに対してこれらの関数を呼び出すことができます。これは、C での抽象化の例です。この特定の例の詳細については、この記事を参照してください。

データ抽象化のもう 1 つの形式は、不透明ポインターです。不透明なデータ型がヘッダー ファイルで宣言されていますが、定義が公開されることはありません。型の定義を知らないコードは、その値にアクセスすることはできず、その値へのポインターのみを使用します。ウィキペディアの不透明なデータ型不透明なポインターを参照してください。

おそらく遭遇したことのある不透明なデータ型の例はFILE、stdio.h にあります。FILE *が指す実際のデータは異なりますが、すべてのオペレーティング システムで同じインターフェイスが使用されます。FILE *を呼び出してを取得し、fopen他のさまざまな関数呼び出しで操作できますが、それが指すデータが表示されない場合があります。

CI でのオブジェクト指向プログラミングの詳細については、無料のオンライン ブックObject Oriented Programming in ANSI-C をお勧めします。このドブス博士の記事をご覧ください。関連する質問: C でのオブジェクト指向およびCでオブジェクト指向コードを作成できますか? .

于 2015-07-22T14:35:12.267 に答える
2

C では非表示は簡単で、単にキャストするだけです。

OOPは実行されるかもしれませんが、一部の機能を取得するのはあまり便利ではないと思います (例: 継承) 多分ポリモーフィズムは達成されていると思いますが、自宅で試したことはありません!

ネイティブ C++ ライブラリへのCインターフェイスは一般的で、次のようなものです。

void *obj_create(void); /* return obscure ptr */
int obj_method(void *obj, int somearg);
void obj_destroy(void *obj);

プライベートヘッダーをパブリック分散から分離することです。

編集

AmigaOSには、何年も前から機能している C の基本的な OOP 実装があり、少なくともAROSプロジェクトからまだ使用されています。実装はBOOPSIと呼ばれ、GUI ガジェット (ウィジェット) の一部の基盤でもありますが、説明するためだけに使用できます。objects、ここで簡単な紹介( Amiga Rom Kernel Reference Manualでは、それを使用してより多くのオブジェクトにシグナルをブロードキャストする方法が示されています。これは、パイオニア Qt のスロット/シグナルの実装です)。

私は過去数日間Nim langを調べていましたが、gcc/clang/tinycc などのバックエンドでコンパイルする C コードを生成し (無効になっている可能性のあるランタイムを追加)、いくつかの OOP をサポートしています。

于 2013-10-06T14:32:08.237 に答える