質問

私はビデオの再生と録画に使用されるクラスのコレクションに取り組んでいます。パブリックインターフェイスのように機能するメインクラスが1つあり、次のようなメソッドがあります。 play(), stop(), pause(), record() 等...次に、ビデオのデコードとエンコードを行う主力クラスを用意します。

C++ にネストされたクラスが存在することを知りました。プログラマがそれらのクラスを使用することについてどう考えているのか知りたいと思っています。私は少し警戒心があり、利点と欠点が何であるかよくわかりませんが、(私が読んでいる本によると)私のような場合に使用されるようです。

この本では、私のようなシナリオでは、主力クラスをインターフェイス クラス内にネストするのが良い解決策であると示唆しています。これにより、クライアントが使用する予定のないクラスに個別のファイルが存在せず、名前の衝突の可能性を回避できます。これらの正当化については知りません。ネストされたクラスは私にとって新しい概念です。プログラマーがこの問題についてどう考えているか知りたいだけです。

役に立ちましたか?

解決

ここでネストされたクラスを使用することには少し抵抗があります。バックエンドのもの (主力) を処理する「マルチメディア ドライバー」の抽象基本クラスを作成し、フロントエンドの作業用に別のクラスを作成した場合はどうなるでしょうか?フロントエンド クラスは、(適切なメディア タイプと状況に応じて) 実装されたドライバー クラスへのポインター/参照を受け取り、主力構造に対して抽象操作を実行できます。

私の哲学は、両方の構造が並行して使用されることを前提として、洗練された方法でクライアントがアクセスできるようにすることです。

私は次のようなものを参照します QTextDocument Qtで。ベアメタルデータ処理への直接インターフェイスを提供しますが、操作を行う権限を QTextEdit などのオブジェクトに渡します。

他のヒント

ネストされたクラスを使用して、メイン クラスの実装に必要な (小さな) ヘルパー クラスを作成します。または、たとえば、インターフェイス (抽象メソッドを持つクラス) を定義します。

この場合、ネストされたクラスの主な欠点は、クラスの再利用が難しくなることです。おそらく、VideoDecoder クラスを別のプロジェクトで使用したいと思うでしょう。これを VideoPlayer のネストされたクラスにすると、これをエレガントな方法で行うことはできません。

代わりに、他のクラスを別の .h/.cpp ファイルに配置し、VideoPlayer クラスで使用できるようにします。VideoPlayer のクライアントは、VideoPlayer を宣言するファイルをインクルードするだけで済み、それをどのように実装したかを知る必要はありません。

ネストされたクラスを使用するかどうかを決定する 1 つの方法は、このクラスが補助的な役割を果たすのか、それとも独自の役割を果たすのかを考えることです。

別のクラスを支援することのみを目的として存在する場合は、通常、それをネストされたクラスにします。それには注意すべき点が山ほどあり、中には矛盾しているように思えるものもあるが、結局は経験と直感次第だ。

を使用できるケースのように聞こえます 戦略パターン

実装クラスをユーザーから隠すことが適切な場合もあります。このような場合は、実装クラスをパブリック クラス定義内に置くよりも foo_internal.h 内に置く方が良いでしょう。こうすることで、foo.h の読者には問題が発生しないようにしたい内容が表示されなくなりますが、インターフェイスの具体的な実装のそれぞれに対してテストを作成することができます。

半古い Sun C++ コンパイラと、標準では動作が変更された入れ子になったクラスの可視性に関する問題が発生しました。もちろん、これはネストされたクラスを実行しない理由ではありません。古いコンパイラを含む多くのプラットフォームでソフトウェアをコンパイルする予定がある場合に注意すべき点です。

さて、インターフェイス クラスで主力クラスへのポインタを使用し、それらをインターフェイス メソッドのパラメータまたは戻り値の型として公開しない場合は、これらの主力クラスの定義をインターフェイス ヘッダー ファイルに含める必要はありません (単に、代わりにそれらを前方宣言します)。こうすることで、インターフェイスのユーザーはバックグラウンドのクラスについて知る必要がなくなります。

このためにクラスをネストする必要はありません。実際、クラス ファイルを分けると、プロジェクトが成長するにつれてコードがはるかに読みやすくなり、管理が容易になります。また、後でサブクラス化する必要がある場合にも役立ちます (たとえば、さまざまなコンテンツ/コーデック タイプの場合)。

詳細については、こちらをご覧ください。 PIMPL パターン (セクション3.1.1)。

内部クラスは、外部クラスとなるはずのパブリック インターフェイスを使用して別のクラスとして実装できない場合にのみ使用する必要があります。内部クラスはクラスのサイズ、複雑さ、責任を増大させるため、使用は控えめにする必要があります。

あなたのエンコーダ/デコーダクラスは、よりよく適合しているように思えます 戦略パターン

ネストされたクラスを避ける理由の 1 つは、コードを swig (http://www.swig.org) 他の言語で使用するためのものです。現在、Swig にはネストされたクラスに関する問題があるため、ネストされたクラスを公開するライブラリとのインターフェースは非常に困難になります。

もう 1 つ留意すべきことは、作業機能 (デコードやエンコードなど) のさまざまな実装を想像したことがあるかどうかです。その場合、関数を実装するさまざまな具象クラスを持つ抽象基本クラスが必ず必要になります。実装の種類ごとに個別のサブクラスをネストすることは実際には適切ではありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top