4

thisメンバー関数は、ポインターを明示的に渡すことにより、C でエミュレートできます。仮想関数は、関数ポインターのグローバル配列へのポインターをすべてのオブジェクトに明示的に格納することによってエミュレートできます。罰金。

私の質問は、人々は実際にこれを行うのですか? このテクニックを教える価値があるかどうか疑問に思っています。実世界で実際に使用されることのないものを C の新入生に教えたくないからです。

(すでに OOP に精通している人々のための 2 週間の入門 C コースの最終日を埋める必要があります。)

説明されている方法で C で OO をエミュレートする関連プロジェクト、ライブラリ、またはフレームワークはありますか?

4

5 に答える 5

8

私は C で約 20 年の経験があります。これは私が最初に学んだコンパイル済み言語であり、先に進む必要がなかったため、ずっと C であり、C のみでした。私は仕事でも家でも常にコードを書いています。ロックフリーのデータ構造のライブラリを公開しました。私は有能な C プログラマーだと思います。

ご質問のとおり、オブジェクト指向はいくつかの概念から構成されています。たとえば、1 つはインスタンス化です。たとえば、new() と delete() を含むライブラリと、特定のエンティティ (スタック、リストなど) のインスタンスです。C はこれをサポートしており、もちろん非常に機能的で便利なアプローチです。私はこのアプローチを約 15 年間使用してきました。

何年も前に、C++ で十分にサポートされている別のオブジェクト指向の概念である継承の実験を始めました。他のエンティティを含むエンティティが必要でした。問題は、含まれているエンティティの API を公開することです。それはできますが、実際には、C 言語はそのような概念やアプローチを自然に表現するものではありません。今使っているものではありません。

私のアドバイスは次のとおりです。ナイフはナイフ、フォークはフォーク。どちらも他方として使用できますが、うまく機能しません。C は、継承などの (重要な) オブジェクト指向の概念を当然サポートしていません。C にこれらのことをさせようとしないでください。これを行う場合は、C++ を使用してください。

于 2012-08-12T12:17:48.413 に答える
3

はい、彼らがやります。

説明されている方法で C で OO をエミュレートする関連プロジェクト、ライブラリ、またはフレームワークはありますか?

一流の言語サポートがないという理由だけで、それを「エミュレート」とは呼びません。GObjectを参照してください。

于 2012-08-12T11:41:13.823 に答える
2

多くのプロジェクトは、C コードベースでオブジェクト指向のパラダイムを使用しています。さまざまな理由から、彼らは CPP を直接使用していません。システム レベルまたはパフォーマンス集約型のプロジェクトの場合、他の言語では対応できません。したがって、cppとcの間の戦いです。

本格的な CPP ではなく C で OO をエミュレートする理由は、激しい議論のトピックです。Linus Torvalds はかつて、CPP コンパイラは信頼できないと述べたことで有名です。彼は、CPP で生成されたコードをほとんど信頼していません。

Linux カーネルは、C で OO 設計パターンを実装する良い例です。Linux カーネルがどのようにそれを行ったかについては、次の lwn.net 記事シリーズで読むことができます。

パート1

パート2

C での OO 設計パターンの全範囲の実装をカバーする広範な無料のドキュメントがインターネット上に転がっています。

ooc.pdf

同じ道に沿って他の多くのプロジェクトを見つけることができます。

例:

pjsip

ソフィア

于 2012-08-12T12:05:21.070 に答える
1

実際には使用されないかもしれませんが、メンバー関数とオブジェクトを最初のパラメーターとして取る関数との間の同等性の概念を学ぶことは非常に価値があります。彼らの頭の後ろにこの概念を持っていることは彼らが将来遭遇するであろう多くの問題で彼らを助けるでしょう。

毎日、Stack Overflowで、関数ポインターを必要とするものにメンバー関数を渡すことが機能しない理由などについて質問する人がいます。彼らは、メンバー関数はオブジェクトの一部である魔法の関数であり、状況全体を複雑にしすぎていると考えています。メンバー関数がオブジェクトを最初のパラメーターとして受け取る関数と同等であることに気付いた場合、彼らが抱えている問題(メソッドを呼び出すには、メンバー関数ポインターとオブジェクトの両方が必要になる)。考えられる解決策(オブジェクトを個別に渡すか、オブジェクトをキャプチャする何らかのクロージャを作成する)も明らかになります。どうやら、あまりにも多くの人がOOが「魔法」であると偽って、これを理解していないようです。

関数型プログラミングでは、データ構造やローカル変数など、すべてを関数の操作の観点から純粋に記述する方法を人々に教えることがよくあります。これが実用的であるというわけではありません-おそらく非効率的です-しかし、これは彼らに機能の力について何かを印象づけます。そしてそれは彼らが別の方法で物事を理解するのを助けます。そして、もし彼らがコンパイラーか何かを書くなら、おそらく将来的には、これらの同等性が役に立つでしょう。

コンピュータサイエンスとは、同等性と削減、そしてある問題を別の問題の観点から考える方法です。SAT-3をサブセット和に減らします。これは、実際にSAT-3問題を解決する方法ではなく、サブセット和がNP完全であることを示しているためです。

たまに、他の誰かが書いたコードに出くわします。インスタンス以外のメソッドが引数として構造体へのポインターを取り、パターンと電球が頭の中で消えるのを見て、私はたとえば、ああ、これはインスタンスメソッドにリファクタリングできます。これは、この同等性について知っているからです。ご覧のとおり、これらの同等性を知ることは、より優れた、より単純なコードを書くのにも役立ちます。

于 2012-08-12T21:51:03.103 に答える
0

TI の「DSP Algorithm Standard」/xDAIS フレームワークを確認してください。

適合するすべての DSP アルゴリズム実装が実装する汎用 C API があります (同語反復で申し訳ありません)。このすべての「アート」の必要性は、DSP の世界に共通するいくつかの問題から生じています。

  • 比較的小さい RAM
  • 複数のデータ チャネル (多くの場合、並列/同時)
  • 複雑なアルゴリズムの使用パターン
  • 私が忘れている他の何か

この標準とフレームワークは、DSP エンジニアがサードパーティの DSP アルゴリズムを簡単に使用できるようにすることを目的としています。

アルゴリズム インスタンスを構成し、(構成に基づいて) そのメモリ要件を照会するためのインターフェイスがあり、メモリを実際に管理するサポート関数があります。

一部のメモリ領域 (スクラッチパッド) は、一時的に割り当てられ、アクティブなアルゴリズム インスタンスに割り当てられ、非アクティブなアルゴリズム インスタンスから取り除かれ、別のインスタンスに割り当てられ、効果的に共有されます。

インスタンス メモリ バッファを最適化メモリに移動する機能 (および API) もあります。

もっとありますが、詳細を思い出すためにドキュメントを読み直す必要があります。

たとえば、メソッドIALG_*()とインターフェイス メソッドを参照してください。ALG_*()

また、汎用 API の実装を検証するためのツールもあります。サードパーティは、TI にそれらの正式な検証を要求できます。

関連リンク: spru352g.pdfspru360e.pdf

于 2012-08-12T14:06:13.730 に答える